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 */