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

单链表

2016-03-07 00:00 323 查看
基本操作: 创建、查找、删除、插入

1 #include<stdio.h>  2 #include<stdlib.h>  3 #include<time.h>  4  5 #define OK 1  6 #define ERROR 0  7 #define TRUE 1  8 #define FALSE 0  9 #define ElementType int  10  11 typedef int Status;  12 typedef struct Node{  13  ElementType Element;  14 struct Node *Next;  15 }Node;  16 typedef struct Node LinkList;  17  18 int InitList(LinkList *L)  19 {  20 L = (LinkList*)malloc(sizeof(Node)); //给指针分配空间  21 if(!(L))  22  {  23 return ERROR;  24  }  25 L ->Next = NULL; //  26 return OK;  27 }  28 int ListLength(LinkList *head)  29 {  30 int length =0;  31 LinkList *p = head -> Next;  32 while(p  != NULL)  33  {  34 length ++;  35 p  = p->Next;  36  }  37 return length;  38 }  39 /*将元素插入到链表的第i个位置*/  40 int InsertList(ElementType e,int i,LinkList *head)  41 {  42 LinkList *p = head ;  43 LinkList *temp;  44 if(i <= ListLength(head))  45  {  46 while(i-1)  47  {  48 p = p->Next;  49 i--;  50 } //p是第i个结点的前一个结点  51 temp = (Node*)malloc(sizeof(LinkList));  52 temp ->Element = e;  53 temp ->Next = p ->Next;  54 p -> Next = temp;  55 return OK;  56  }  57 else  58  {  59 return ERROR;  60  }  61 }  62 //将列表中的元素输出  63 void ListTraverse(LinkList *head)  64 {  65 LinkList *p = head -> Next;  66 while(p)  67  {  68 printf("%d ",p->Element);  69 p = p ->Next;  70  }  71 }  72 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */  73 /* 操作结果:删除list的第i个数据元素,并用e返回其值,list的长度减1 */  74 Status ListDelete(LinkList *head,int i,ElementType *e)  75 {  76 LinkList *p = head;  77 LinkList *temp;  78 if(i <= ListLength(head))  79  {  80 while(i-1)  81  {  82 p = p -> Next;  83 i--;  84 } //p指向被删除结点的前一项  85 temp = p -> Next;  86 p -> Next = temp ->Next;  87 free(temp);  88 return OK;  89  }  90 else  91 return ERROR;  92 }  93 /*得到head中第i个元素的值*/  94 ElementType GetElement(LinkList *head,int i)  95 {  96 LinkList *p = head;  97 // LinkList *temp;  98 if(i <= ListLength(head))  99  { 100 while(i) 101  { 102 p = p -> Next; 103 i--; 104 } //p指向第i个结点 105 106 return p ->Element;; 107  } 108 else 109 return ERROR; 110 } 111 112 /* 113 声明一个结点temp和计数器变量i 114 初始化一空链表L 115 循环 116  初始化temp 117  temp插入到头结点和前一新结点之间 118 *********************************************************** 119 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */ 120 void CreateListHead(LinkList *L, int n) 121 { 122 LinkList *temp; 123 int i; 124 srand(time(0)); 125 L = (LinkList*)malloc(sizeof(Node)); 126 for(i = 0;i < n; i++) 127  { 128 temp = (LinkList*)malloc(sizeof(Node)); 129 temp -> Element = rand() %100 +1; 130 temp -> Next = L ->Next; 131 L -> Next = temp; 132  } 133 134 } 135 //尾插法 136 void CreateListTail(LinkList *L,int n) 137 { 138 LinkList *temp,*p; 139 int i; 140 141 L = (LinkList*)malloc(sizeof(Node)); 142 p = L; 143 for(i =0;i < n; i++) 144  { 145 temp = (LinkList*)malloc(sizeof(Node)); 146 temp  -> Element = rand()%100 +1; 147 p -> Next= temp; 148 p = temp; 149 150  } 151 p -> Next = NULL; 152 153 } 154 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */ 155 Status ClearList(LinkList *L) 156 { 157 LinkList *q,*p; 158 p = L-> Next; 159 while(p  != NULL) 160  { 161 q = p -> Next; 162 free(p); 163 p = q; 164  } 165 L -> Next = NULL; 166 return OK; 167 } 168 /*********************************** 169 **************列表反转的3种方法**** 170 *********************************** 171 ListReverse1 172 173 */ 174 LinkList* ListReverse1 (LinkList *L) 175 { 176 LinkList *current; 177 LinkList *p; 178 179 current = L -> Next; 180 while(current -> Next  != NULL) 181  { 182 p = current -> Next; 183 current -> Next = p -> Next ; 184 p -> Next = L -> Next; 185 L -> Next = p; 186  } 187 return L; 188 } 189 LinkList* LisReverse2(LinkList *L) 190 { 191 LinkList *current ,*pnext,*prev; 192 if(L == NULL || L -> Next == NULL) 193 return L; 194 current = L->Next; 195 pnext = current -> Next; 196 current -> Next = NULL; 197 while(pnext) 198  { 199 prev = pnext -> Next; 200 pnext -> Next = current; 201 current = pnext; 202 pnext = prev; 203  } 204 L -> Next = current; 205 return L; 206 } 207 int HasLoop (LinkList *L) 208 { 209 LinkList *q,*p; 210 int step1 = 0; 211 212 213 q = L -> Next; 214 while(q) 215  { 216 step1++; 217 int step2 = 0; 218 p = L -> Next; 219 while(p) 220  { 221 step2++; 222 if(p == q) 223  { 224 if(step1 == step2) 225 break; 226 else 227 return 1; 228  } 229 p = p -> Next; 230  } 231 q = q -> Next; 232  } 233 return 0; 234 } 235 void CreateLoop(LinkList *L ,int num) 236 { 237 int i;//count 238 LinkList *current; 239 LinkList *p = L -> Next; 240 for(i = 0;i < num; i++) 241  { 242 if(p == NULL) 243  { 244 return 0; 245  } 246 p = p -> Next; 247  } 248 current = p; 249 while(p->Next) 250  { 251 p = p -> Next; 252  } 253 p -> Next = current; 254 return 1; 255 } 256 int main() 257 { 258 LinkList *l; 259  InitList(l); 260  ListLength(l); 261 return 0; 262 }


距离-标尺问题

*求单链表的倒数第k个数,声明2个指针,一个指针先走k步,然后两个指针一起走。当第一个指针next == NULL时,di二个指针就是倒数第k个结点的值。

*用标尺法求未知长度单链表的中间节点

**声明2个指针,search,mid。search指针的移动速度是mid指针的2倍,当search指针到达链表结尾时。mid指针到达链表中间。

判断链表是否有环

*使用2个快慢指针可以判断。如果有环,它们在某点相遇。

int HasLoop (LinkList *L) { LinkList *q,*p; q =p =L -> Next; int stepq//length of q int stepp //length of p while(p != NULL && q != NULL && q -> Next != NULL) { p = p -> Next; if(q -> Next != NULL) q = q -> Next -> Next; if(q = p) return 1 } return 0; }


*第二种方法 和嵌套循环类似 设2个指针q、p,p走一步,q每次从头走到结束。如果有环,结点相同时步数不相等。

int HasLoop (LinkList *L) { LinkList *q,*p; int step1 = 0; q = L -> Next; while(q) { step1++; int step2 = 0; p = L -> Next; while(p) { step2++; if(p == q) { if(step1 == step2) break; else return 1; } p = p -> Next; } q = q -> Next; } return 0; }


单链表建环

*将最后一个结点与第num个结点连接起来。使用循环遍历到第num个结点,声明current指针用来保存结点。将指针p循环到最后,将p和current连接起来。

void CreateLoop(LinkList *L ,int num) { int i;//count LinkList *current; LinkList *p = L -> Next; for(i = 0;i < num; i++) { if(p == NULL) { return 0; } p = p -> Next; } current = p; while(p->Next) { p = p -> Next; } p -> Next = current; return 1; }


删除链表中重复的元素

*声明指针p从第一个结点循环到最后一个,每次循环时用指针q,从p遍历到最后一个指针。如果有重复的结点 free()掉

Thanks> http://www.nowamagic.net/librarys/veda/detail/2241
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构