单链表及其算法演示(Data structure course from HaoBin)
专业术语:
首节点:指的是存放有效数据的第一个节点;
尾节点:指的是存放有效数据的最后一个节点;
头节点:为首节点之前的一个节点,数据类型和首节点是一模一样的,头节点不存放有效数据,设置头节点的目的是为了方便对链表的操作;
头指针:为指向头节点的指针变量。
对算法的理解:
狭义的算法是与数据的存储密切相关的;
广义的算法是与数据的存储无关的
泛型:利用某种技术达到的效果就是,不同的存储方式,操作是一样的(如以下例子中的冒泡排序)。
关于如何看懂一个程序:
1)看懂程序流程;
2)看懂每一个语句的功能;
3)试数。
1 #include <stdio.h> 2 #include <malloc.h> 3 #include <stdlib.h> 4 5 typedef enum{false, true} bool; //自定义bool类型 6 7 struct Node 8 { 9 int data; //数据域 10 struct Node * pNext; //指针域 11 }; 12 13 struct Node * create_list(void); //创建一个单链表 14 void traverse_list(struct Node * pHead); //遍历链表输出 15 bool is_empty(struct Node * pHead); //判断链表是否为空 16 int length_list(struct Node * pHead); //求链表的有效节点个数 17 void sort_list(struct Node * pHead); //冒泡排序 18 bool insert_list(struct Node * pHead, int pos, int val); //插入一个有效节点 19 bool delete_list(struct Node * pHead, int pos, int * pVal); //删除一个有效节点 20 21 int main(void) 22 { 23 struct Node * pHead = NULL; //定义头指针 24 int pVal; 25 26 pHead = create_list(); 27 printf("the list:"); 28 traverse_list(pHead); 29 30 printf("length of list : %d\n", length_list(pHead)); 31 32 if (is_empty(pHead)) 33 printf("the list is empty.\n"); 34 else 35 printf("the list is not empty.\n"); 36 37 sort_list(pHead); 38 printf("the sorted list:"); 39 traverse_list(pHead); 40 41 insert_list(pHead, 4, 999); 42 printf("insert node list:"); 43 traverse_list(pHead); 44 45 delete_list(pHead, 4, &pVal); 46 printf("delete node list:"); 47 traverse_list(pHead); 48 49 return 0; 50 } 51 52 /* 创建一个单链表 */ 53 struct Node * create_list(void) 54 { 55 int len; //有效节点的个数 56 int i; 57 int val; //用来临时存放链表的数据 58 59 printf("please input the number of nodes:"); 60 scanf("%d", &len); 61 62 //创建一个不存放有效数据的头节点 63 struct Node * pHead = (struct Node *)malloc(sizeof(struct Node)); 64 if (NULL == pHead) 65 { 66 printf("failed to allocate memory.\n"); 67 exit(-1); //退出程序 68 } 69 //定义一个指针,用来总是指向链表的最后一个节点 70 struct Node * pTail = pHead; 71 pTail->pNext = NULL; 72 73 for (i=0; i<len; i++) 74 { 75 printf("please input the data of %d node:", i+1); 76 scanf("%d", &val); 77 78 struct Node * pNew = (struct Node *)malloc(sizeof(struct Node)); 79 if (NULL == pHead) 80 { 81 printf("failed to allocate memory.\n"); 82 exit(-1); 83 } 84 else 85 { 86 pNew->data = val; 87 pNew->pNext = NULL; 88 pTail->pNext = pNew; 89 pTail = pNew; 90 } 91 } 92 return pHead; 93 } 94 95 /* 链表的遍历输出 */ 96 void traverse_list(struct Node * pHead) 97 { 98 struct Node * p = pHead->pNext; 99 100 while (NULL != p) 101 { 102 printf("%d ", p->data); 103 p = p->pNext; 104 } 105 printf("\n"); 106 107 return; 108 } 109 110 /* 判断链表是否为空 */ 111 bool is_empty(struct Node * pHead) 112 { 113 if (NULL == pHead->pNext) 114 return true; 115 else 116 return false; 117 } 118 119 /* 求链表有效节点的个数 */ 120 int length_list(struct Node * pHead) 121 { 122 struct Node * p = pHead->pNext; 123 int len = 0; 124 125 while (NULL != p) 126 { 127 len++; 128 p = p->pNext; 129 } 130 131 return len; 132 } 133 134 /* 冒泡排序,升序 */ 135 void sort_list(struct Node * pHead) 136 { 137 int i, j, t; 138 struct Node * p; 139 struct Node * q; 140 int len; 141 142 len = length_list(pHead); 143 144 for (i=0, p=pHead->pNext; i<len-1; i++,p=p->pNext) 145 { 146 for (j=i+1, q=p->pNext; j<len; j++, q=q->pNext) 147 { 148 if (p->data > q->data) 149 { 150 t = p->data; 151 p->data = q->data; 152 q->data = t; 153 } 154 } 155 } 156 157 return; 158 } 159 160 /* 插入一个有效节点,在第pos个有效节点前插入 */ 161 bool insert_list(struct Node * pHead, int pos, int val) 162 { 163 int i = 0; 164 struct Node * p = pHead; 165 struct Node * q = NULL; 166 167 while (NULL!=p && i<pos-1) 168 { 169 p = p->pNext; 170 i++; 171 } 172 if (NULL==p || i>pos-1) 173 return false; 174 175 struct Node * pNew = (struct Node *)malloc(sizeof(struct Node)); 176 if (NULL == pHead) 177 { 178 printf("failed to allocate memory.\n"); 179 exit(-1); 180 } 181 pNew->data = val; 182 q = p->pNext; 183 p->pNext = pNew; 184 pNew->pNext = q; 185 186 return true; 187 } 188 189 /* 删除第pos个有效节点 */ 190 bool delete_list(struct Node * pHead, int pos, int * pVal) 191 { 192 int i = 0; 193 struct Node * p = pHead; 194 struct Node * q = NULL; 195 196 while (NULL!=p->pNext && i<pos-1) 197 { 198 p = p->pNext; 199 i++; 200 } 201 if (NULL==p->pNext || i>pos-1) 202 return false; 203 204 q = p->pNext; 205 *pVal = q->data; 206 p->pNext = p->pNext->pNext; 207 free(q); 208 q = NULL; 209 210 return true; 211 } 212 /* 213 The output results in Code::Blocks 10.05 214 ----------------------------------------------------- 215 please input the number of nodes:5 216 please input the data of 1 node:55 217 please input the data of 2 node:44 218 please input the data of 3 node:33 219 please input the data of 4 node:22 220 please input the data of 5 node:11 221 the list:55 44 33 22 11 222 length of list : 5 223 the list is not empty. 224 the sorted list:11 22 33 44 55 225 insert node list:11 22 33 999 44 55 226 delete node list:11 22 33 44 55 227 228 Process returned 0 (0x0) execution time : 7.860 s 229 Press any key to continue. 230 ----------------------------------------------------- 231 */