C語言版本:單鏈表的實現(優化版本)

未優化版本:http://www.cnblogs.com/duwenxing/p/7569376.htmlhtml

slist.h優化

 1 #ifndef __SLIST_H__
 2 #define __SLIST_H__
 3 
 4 #include<cstdio>
 5 #include<malloc.h>
 6 #include<assert.h>
 7 typedef int ElemType;
 8 typedef struct Node { //定義單鏈表中的結點信息
 9     ElemType data; //結點的數據域
10     struct Node *next; //結點的指針域
11 }Node,*PNode;
12 typedef struct List { //定義單鏈表的鏈表信息
13     PNode first; //first指向單鏈表中的第一個結點
14     PNode last; //last指向單鏈表中的最後一個結點
15     size_t size; //記錄單鏈表中的結點個數
16 }List;
17 
18 void InitList(List *list);//初始化單鏈表
19 void push_back(List *list, ElemType x);//在單鏈表的末尾插入元素
20 void push_front(List *list, ElemType x);//在單鏈表的頭部插入元素
21 void show_list(List *list);//打印單鏈表
22 void pop_back(List *list);//刪除單鏈表的最後一個元素
23 void pop_front(List *list);//刪除單鏈表的第一個元素
24 void insert_val(List *list, ElemType val);//將數據元素插入到單鏈表中(要求此時單鏈表中的數據元素順序排列)
25 Node* find(List *list, ElemType x);//查找單鏈表中數據值爲x的結點
26 int length(List *list);//求單鏈表的長度
27 void delete_val(List *list, ElemType x);//按值刪除單鏈表中的某個數據元素
28 void sort(List *list);//對單鏈表進行排序
29 void reverse(List *list);//逆置單鏈表
30 void clear(List *list);//清除單鏈表
31 void destroy(List *list);//摧毀單鏈表
32 
33 //代碼優化 34 Node* CreateNode(ElemType x); //建立一個單鏈表結點 35 Node* begin(List *list); //返回單鏈表的第一個結點 36 Node* end(List *list); //返回單鏈表中最後一個結點的下一個結點 37 void insert(List *list, Node *pos, ElemType x); //在單鏈表的特定位置(pos)插入新的結點 38 
39 #endif //__SLIST_H__

 

slist.cppui

  1 #include"slist.h"
  2 
  3 void InitList(List *list) {
  4     list->first = list->last = (Node*)malloc(sizeof(Node)); //頭結點
  5     assert(list->first != NULL);
  6     list->first->next = NULL;
  7     list->size = 0;
  8 }
  9 
 10 //push_back的優化
 11 void push_back(List *list, ElemType x) { 12 insert(list, end(list), x); 13 }  14 
 15 //push_front的優化
 16 void push_front(List *list, ElemType x) { 17 insert(list, begin(list), x); 18 }  19 
 20 void show_list(List *list) {
 21     //step 1:指針p指向單鏈表的第一個結點
 22     Node *p = list->first->next;
 23     //step 2:循環打印結點的信息
 24     while (p != NULL) {
 25         printf("%d->", p->data);
 26         p = p->next;
 27     }
 28     printf("Nul.\n");
 29 
 30 }
 31 
 32 void pop_back(List *list) {
 33     //step 1:判斷單鏈表是否爲空
 34     if (list->size == 0) return;
 35     //step 2:定義指針p使其指向目標結點的前一個結點
 36     Node *p = list->first;//從頭結點開始
 37     while (p->next != list->last)
 38         p = p->next;
 39     //step 3:刪除目標結點
 40     free(list->last);
 41     list->last = p;
 42     list->last->next = NULL;
 43     //step 4:更新單鏈表的長度
 44     list->size--;
 45 }
 46 
 47 void pop_front(List *list) {
 48     //step 1:判斷單鏈表是否爲空
 49     if (list->size == 0) return;
 50     //step 2:定義指針p使其指向目標結點的前一個結點
 51     Node *p = list->first->next;
 52     //step 3:刪除目標結點
 53     list->first->next = p->next;
 54     free(p);
 55     //step 4:判斷刪除的結點是不是單鏈表的最後一個結點,如果則更新單鏈表的尾指針
 56     if (list->size == 1)
 57         list->last = list->first;
 58     //step 4:更新單鏈表的長度
 59     list->size--;
 60 }
 61 
 62 //insert_val的優化
 63 void insert_val(List *list, ElemType x) {
 64     //step 1:建立一個新的結點
 65 Node *s = CreateNode(x);  66     //step 2:定義指針p使其指向待插入位置的前一個結點
 67     Node *p = list->first;//從頭結點開始
 68     while (p->next != NULL && p->next->data < s->data)
 69         p = p->next;
 70     //step 3:判斷結點的待插入位置是不是表尾,如果則更新單鏈表的尾指針
 71     if (p->next == NULL)
 72         list->last = s;
 73     //step 4:插入結點
 74     s->next = p->next;
 75     p->next = s;
 76     //step 5:更新單鏈表長度
 77     list->size++;
 78 }
 79 
 80 Node* find(List *list, ElemType x) {
 81     //step 1:指針p指向單鏈表的第一個結點
 82     Node *p = list->first->next;
 83     //step 2:按照循環順序查找鏈表結點
 84     while (p != NULL && p->data != x)
 85         p = p->next;
 86     return p;
 87 }
 88 
 89 int length(List *list) {
 90     return list->size;
 91 }
 92 
 93 void delete_val(List *list, ElemType x) {
 94     //step 1:判斷單鏈表是否爲空
 95     if (list->size == 0) return;
 96     //step 2:肯定結點在單鏈表中的位置,並判斷其是否存在於單鏈表中
 97     Node *p = find(list, x);
 98     if (p == NULL) {
 99         printf("要刪除的數據不存在!\n");
100         return;
101     }
102     //step 3:判斷結點位置是不是表尾
103     if (p == list->last)//是表尾
104         pop_back(list);
105     else {//不是表尾
106         Node *q = p->next;
107         p->data = q->data;
108         p->next = q->next;
109         free(q);
110         list->size--;
111     }
112 }
113 
114 void sort(List *list) {
115     //step 1:判斷單鏈表中的結點數是否爲0或1
116     if (list->size == 0 || list->size == 1) return;
117     //step 2:將單鏈表中第一個結點以後的鏈表部分截出,方便從新按順序插入鏈表之中
118     Node *s = list->first->next; // 指針s指向單鏈表的第一個節點
119     Node *p = s->next;//q指向s後面的結點
120     list->last = s;//單鏈表的尾指針指向單鏈表的第一個結點
121     list->last->next = NULL;//截斷鏈表
122     //step 3:將截出的鏈表中的結點根據其數據域大小從新插入到原來鏈表中
123     while (p != NULL) {
124         s = p;
125         p = p->next;
126         Node *q = list->first;
127         while (q->next != NULL && q->next->data < s->data)
128             q = q->next;
129         if (q->next == NULL)//判斷q此時指向的是不是單鏈表的最後一個結點,如果則更新鏈表的尾指針
130             list->last = s;
131         //將結點從新插入鏈表
132         s->next = q->next;
133         q->next = s;
134     }
135 }
136 
137 void reverse(List *list) {
138     //step 1:判斷單鏈表中的結點數是否爲0或1
139     if (list->size == 0 || list->size == 1) return;
140     //step 2:將單鏈表中第一個結點以後的鏈表部分截出,而後將截出的鏈表中的結點按頭插法從新插入到原鏈表中
141     Node *p = list->first->next;
142     Node *q = p->next;
143     list->last = p;
144     list->last->next = NULL;
145 
146     while (q != NULL) {
147         p = q;
148         q = q->next;
149         p->next = list->first->next;
150         list->first->next = p;
151     }
152 }
153 
154 void clear(List *list) {
155     //step 1:判斷單鏈表是否爲空
156     if (list->size == 0) return;
157     //step 2:釋放單鏈表中的每個結點
158     Node *p = list->first->next;
159     while (p != NULL) {
160         list->first->next = p->next;
161         free(p);
162         p = list->first->next;
163     }
164     //step 3:頭指針和尾指針從新都指向頭結點
165     list->last = list->first;
166     //step 4:更新鏈表長度
167     list->size = 0;
168 }
169 
170 void destroy(List *list) {
171     //step 1:清空單鏈表
172     clear(list);
173     //step 2:釋放頭結點
174     free(list->first);
175     //step 3:頭指針和尾指針都賦值爲空
176     list->first = list->last = NULL;
177 }
178 
179 //優化 180 Node* CreateNode(ElemType x) { 181 Node *s = (Node*)malloc(sizeof(Node)); 182 assert(s != NULL); 183 s->data = x; 184 s->next = NULL; 185 return s; 186 } 187 188 Node* begin(List *list) { 189 return list->first->next; 190 } 191 192 Node* end(List *list) { 193 return list->last->next; 194 } 195 196 void insert(List *list, Node *pos, ElemType x) { 197 //step 1:建立一個新的結點 198 Node *s = CreateNode(x); 199 //step 2:肯定帶插入位置 200 Node *p = list->first; 201 while (p->next != pos) 202 p = p->next; 203 //step 3:插入結點 204 s->next = p->next; 205 p->next = s; 206 //step 4:判斷結點是否插入到鏈表的表尾,如果則更新單鏈表的表尾指針 207 if (pos == NULL) 208 list->last = s; 209 //step 5:更新單鏈表長度 210 list->size++; 211 }

 

main.cppspa

 1 #include"slist.h"
 2 
 3 void main() {
 4     List mylist;
 5     InitList(&mylist);
 6 
 7     ElemType item;
 8     Node *p = NULL;
 9     int select = 1;
10     while (select) {
11         printf("*******************************************\n");
12         printf("*[1]  push_back        [2]  push_front    *\n");
13         printf("*[3]  show_list        [4]  pop_back      *\n");
14         printf("*[5]  pop_front        [6]  insert_val    *\n");
15         printf("*[7]  find             [8]  length        *\n");
16         printf("*[9]  delete_val       [10] sort          *\n");
17         printf("*[11] reverse          [12] clear         *\n");
18         printf("*[13*] destroy         [0] quit_system    *\n");
19         printf("*******************************************\n");
20         printf("請選擇:>>");
21         scanf("%d", &select);
22         if (select == 0) break;
23         switch (select) {
24         case 1:
25             printf("請輸入要插入的數據(-1結束):>");
26             while (scanf("%d", &item), item != -1) {
27                 push_back(&mylist, item);
28             }
29             break;
30         case 2:
31             printf("請輸入要插入的數據(-1結束):>");
32             while (scanf("%d", &item), item != -1) {
33                 push_front(&mylist, item);
34             }
35             break;
36         case 3:
37             show_list(&mylist);
38             break;
39         case 4:
40             pop_back(&mylist);
41             break;
42         case 5:
43             pop_front(&mylist);
44             break;
45         case 6:
46             printf("請輸入要插入的數據:>");
47             scanf("%d", &item);
48             insert_val(&mylist, item);
49             break;
50         case 7:
51             printf("請輸入要查找的數據:>");
52             scanf("%d", &item);
53             p = find(&mylist, item);
54             if (p == NULL)
55                 printf("要查找的數據在單鏈表中不存在!\n");
56             break;
57         case 8:
58             printf("單鏈表的長度爲%d\n", length(&mylist));
59             break;
60         case 9:
61             printf("請輸入要刪除的值:>");
62             scanf("%d", &item);
63             delete_val(&mylist, item);
64             break;
65         case 10:
66             sort(&mylist);
67             break;
68         case 11:
69             reverse(&mylist);
70             break;
71         case 12:
72             clear(&mylist);
73             break;
74             //case 13:
75             //destroy(&mylist);
76             //break;
77         default:
78             printf("選擇錯誤,請從新選擇!\n");
79             break;
80         }
81     }
82     destroy(&mylist); //程序結束,摧毀鏈表
83 }
相關文章
相關標籤/搜索