您的位置:首页 > 理论基础 > 数据结构算法

二、数据结构基础之单链表C语言实现

2020-02-04 19:40 316 查看
1 /*
2  * 二、数据结构基础之单链表
3  * 单链表数据结构(结构的定义+在此结构上的操作)
4  * --- 2012年4月22日 ---by lee
5  */
6
7 #ifndef _LINKED_LIST_H
8 #define _LINKED_LIST_H
9
10 #include "Utility.h"
11
12 typedef int DataType;
13
14 //声明链表结点结构
15 typedef struct _ListNode
16 {
17     DataType data;//数据域
18     struct _ListNode *next;//指针域
19 } ListNode;
20
21 //声明链表结构,单链表由头指针唯一确定
22 //头结点不需要改变,改变的只是头指针的指向
23 typedef ListNode *LinkedList;
24
25
26 //单链表的数据操作
27
28 LinkedList InitLinkedList(void);//初始化一个带头结点的空链表,返回头指针
29 void SwapListNode(ListNode* lnode, ListNode* rnode);//交换链表结点中的元素
30 LinkedList CreateLinkedList(DataType* array, int arrayLength);//创建一个带头结点的单链表,并用数组中的数据来填充
31 LinkedList CreateLinkedListFromHead(void);//采用头插入法创建一个带头结点的单链表,返回头指针
32 LinkedList CreateLinkedListFromTail(void);//采用尾插入法创建一个带头结点的单链表,返回头指针
33 int GetLinkedListLength(LinkedList list);//返回单链表的长度(不包括头结点)
34 ListNode* GetListNode(LinkedList list, int index);//返回指向index位置结点的指针
35 ListNode* LocateListNode(LinkedList list, DataType x);//返回指向第一个值为x的结点的指针
36 void InsertListNode(LinkedList list, int index, DataType x);//在链表中位置index处插入值为x的结点
37 void DeleteListNode(LinkedList list, int index);//删除链表中位于index处的结点
38 void PrintLinkedList(LinkedList list);//打印输出链表
39 void ReverseLinkedList(LinkedList list);//实现单链表的逆置
40 void SortLinkedList(LinkedList list);//对单链表中的元素进行升序排序
41
42
43
44 //初始化一个带头结点的空链表,返回头指针
45 //无论链表是否为空,头指针都是指向头结点的非空指针,统一了对空表和非空表的处理
46 LinkedList InitLinkedList(void)
47 {
48     //生成头结点,head指向头结点
49     LinkedList head=(ListNode*)malloc(sizeof(ListNode));
50     if(head == NULL)
51         Error("Apply HeadNode Failed");
52     head->next=NULL;
53     return head;
54 }
55
56 //交换链表结点中的元素
57 void SwapListNode(ListNode* lnode, ListNode* rnode)
58 {
59     if(lnode==NULL && rnode==NULL)
60         Error("Node is null");
61
62     DataType temp=lnode->data;
63     lnode->data=rnode->data;
64     rnode->data=temp;
65 }
66
67 //采用尾插入法创建一个带头结点的单链表,并用数组中的数据来填充
68 LinkedList CreateLinkedList(DataType* array, int arrayLength)
69 {
70     LinkedList head=InitLinkedList();
71     ListNode *p=NULL;
72     ListNode *rear=head; //rear始终指向尾结点
73     for(int i=0; i<arrayLength; i++)
74     {
75         p=(ListNode*)malloc(sizeof(ListNode));
76         if(p == NULL)
77             Error("Apply Node Failed");
78         p->data=array[i];
79         rear->next=p;
80         rear=p;
81     }
82     rear->next=NULL;
83     return head;
84 }
85
86 //采用头插入法创建一个带头结点的单链表,返回头指针
87 LinkedList CreateLinkedListFromHead(void)
88 {
89     LinkedList head=InitLinkedList();
90     DataType x;
91     ListNode *p=NULL;
92     int flag=1;
93     while(flag)
94     {
95         printf("Input the value of node: ");
96         scanf("%d",&x);
97         p=(ListNode*)malloc(sizeof(ListNode));
98         if(p == NULL)
99             Error("Apply Node Failed");
100         p->data=x;
101
102         //在头结点后插入
103         p->next=head->next;
104         head->next=p;
105
106         printf("\nIs continue? Yes:1; No:0\t Answer: ");
107         scanf("%d",&flag);
108     }
109     return head;
110 }
111
112
113 //采用尾插入法创建一个带头结点的单链表,返回头指针
114 LinkedList CreateLinkedListFromTail(void)
115 {
116     //生成头结点,head指向头结点
117     LinkedList head=InitLinkedList();
118
119     DataType x; //x为结点数据域的值
120     ListNode *p=NULL; //p用来指向新建立的结点
121     ListNode *rear=head; //rear始终指向尾结点
122     int flag=1;
123     while(flag)
124     {
125         printf("Input the value of node: ");
126         scanf("%d",&x);
127         p=(ListNode*)malloc(sizeof(ListNode));
128         if(p == NULL)
129             Error("Apply Node Failed");
130         p->data=x;
131         //在尾结点后插入
132         rear->next=p;
133         //rear始终指向尾结点
134         rear=p;
135         printf("\nIs continue? Yes:1; No:0\t Answer: ");
136         scanf("%d",&flag);
137     }
138     //尾结点的指针域指向空
139     rear->next=NULL;
140     return head;
141 }
142
143 //返回单链表的长度(不包括头结点)
144 int GetLinkedListLength(LinkedList list)
145 {
146     int length=0;
147     ListNode *p=list->next;
148     while(p != NULL)
149     {
150         p=p->next;
151         length++;
152     }
153     return length;
154 }
155
156 //返回指向index位置结点的指针(index从0到length)
157 //index为0时,返回头结点的指针
158 ListNode* GetListNode(LinkedList list, int index)
159 {
160     ListNode *p=list;
161
162     int i=0;
163     while((i<index) && (p->next!=NULL))
164     {
165         p=p->next;
166         i++;
167     }
168     if(i!=index)//i<0或者i>length-1时
169         Error("Index Out of Bounds");
170
171     return p;
172 }
173
174 //返回指向第一个值为x的结点的指针
175 ListNode* LocateListNode(LinkedList list, DataType x)
176 {
177     ListNode *p=list->next;
178     while((p!=NULL) && (p->data!=x))
179     {
180         p=p->next;
181     }
182     return p;//若p为NULL,则查找失败
183 }
184
185
186 //在链表中位置index处插入值为x的结点,index从1到length+1
187 void InsertListNode(LinkedList list, int index, DataType x)
188 {
189     ListNode *node=(ListNode*)malloc(sizeof(ListNode));
190     if(node==NULL)
191         Error("Apply Node Failed");
192     node->data=x;
193
194     //获取指向插入位置前一个位置的结点指针
195     ListNode *p=GetListNode(list,index-1);
196     //插入结点
197     node->next=p->next;
198     p->next=node;
199
200 }
201
202
203 //删除链表中位于index处的结点,index从1到length
204 void DeleteListNode(LinkedList list, int index)
205 {
206     //获取指向删除位置前一个位置的结点指针
207     ListNode *p=GetListNode(list,index-1);
208     //p指向最后一个结点,则出错
209     if(p->next==NULL)
210         Error("Illegal Deleted Position");
211
212     ListNode *delNode=p->next;
213     p->next=delNode->next;
214     free(delNode);
215 }
216
217 //打印输出链表
218 void PrintLinkedList(LinkedList list)
219 {
220     ListNode *p=list->next;
221     while(p != NULL)
222     {
223         printf("%d\t",p->data);
224         p=p->next;
225     }
226     printf("\n");
227 }
228
229 //实现单链表的逆置,改变了原链表的结构
230 //遍历一遍链表,改变指针的指向
231 void ReverseLinkedList(LinkedList list)
232 {
233     //如果链表为空,则返回
234     if(list->next==NULL)
235         return;
236     ListNode *p1=list->next;
237     ListNode *p2=p1->next;//p2指向p1的下一个结点
238     ListNode *r=NULL;//作为临时指针,保存p2的下一个结点
239     p1->next=NULL;//头结点的下一个结点作为逆置后的尾结点置为NULL
240     while(p2!=NULL)
241     {
242         r=p2->next;
243         p2->next=p1;//指针反转
244         //p1和p2后移一位
245         p1=p2;
246         p2=r;
247     }
248     //p1最后指向原链表的尾结点,将head指向p1
249     list->next=p1;
250 }
251
252 //对单链表中的元素进行升序排序(冒泡排序),改变了链表的结构
253 void SortLinkedList(LinkedList list)
254 {
255     //如果链表为空,则返回
256     if(list->next==NULL)
257         return;
258     ListNode *p=NULL;
259     int length=GetLinkedListLength(list);
260     for(int i=1; i<length; i++)
261     {
262         p=list->next;
263         for(int j=0; j<length-i; j++)
264         {
265             if(p->data > p->next->data)
266             {
267                 //只是简单地交换两个结点的数据域
268                 SwapListNode(p,p->next);
269             }
270             p=p->next;
271         }
272     }
273 }
274
275 #endif
276
277 //测试代码
278 /*
279     LinkedList head=CreateLinkedListFromTail();
280     PrintLinkedList(head);
281     printf("list length: %d\n",GetLinkedListLength(head));
282     InsertListNode(head,1,9);
283     InsertListNode(head,1,8);
284     PrintLinkedList(head);
285     DeleteListNode(head,1);
286     PrintLinkedList(head);
287     DeleteListNode(head,GetLinkedListLength(head)+2);
288 */

转载于:https://www.cnblogs.com/programlee/archive/2012/05/05/2485095.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
dfhygryh3653 发布了0 篇原创文章 · 获赞 0 · 访问量 47 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: