标签:等于 学习 free 删除 算法 closed 改变 nbsp open
15:01:58 2019-08-25
学习
22:43:01 2019-08-25
看的太慢了。。。马上要开学了
1 #include<stdio.h> 2 #include<malloc.h> 3 typedef struct Node* PtrToNode; 4 struct Node 5 { 6 int Data; 7 PtrToNode Pred; //前驱 8 PtrToNode Succ; //后继 9 }; 10 PtrToNode Header;//头哨兵 11 PtrToNode Trailer;//尾哨兵 //前面写的双向链表只给 头部加了一个表头(哑节点) 现在给尾部也加一个哑节点 12 int size; //规模 13 14 void Init(); //初始化 15 PtrToNode InsertPred(int Element); //前插入 16 PtrToNode InsertSucc(int Element); //后插入 17 int Size(); //返回列表当前规模(节点总数) 18 PtrToNode First() { return Header->Succ; } //返回首节点位置 19 PtrToNode Last() { return Trailer->Pred;} //返回末节点位置 20 PtrToNode InsertAsFirst(int Element); //将元素E当首节点插入 21 PtrToNode InsertAsLast(int Element) { InsertBefore(Trailer, Element); } //将元素E当末节点插入 22 PtrToNode InsertBefore(PtrToNode P, int Element); //将元素E当作P的前驱元插入 23 PtrToNode InsertAfter(PtrToNode P, int Element); //将元素E当作P的后驱元插入 24 int Remove(PtrToNode P); //删除节点 返回删除的数据 25 int Disordered(); //判断所有节点是否有按非降序排列 26 void Sort(); //调整各节点的位置 使之按非降序排列 27 PtrToNode Find(int Element,int n,PtrToNode P); //查找目标元素E(从P(不包括)到P节点前n个元素) 失败时返回NULL 28 PtrToNode Search(int Element,int n,PtrToNode P); //在P节点前的n个元素中 查找E 返回不大于E且秩最大的节点 29 int DeDuplicate(); //剔除重复元素 30 int Uniquify(); //剔除重复元素 31 void Traverse(); //遍历列表 32 33 34 35 void Init() 36 { 37 Header = (PtrToNode)malloc(sizeof(Node)); 38 Trailer = (PtrToNode)malloc(sizeof(Node)); 39 Header->Succ = Trailer; Header->Pred = NULL; 40 Trailer->Pred = Header; Trailer->Succ = NULL; 41 size = 0; 42 } 43 44 //无序列表 45 int VisitByRank(int r) //寻秩序访问 效率低下 46 { 47 PtrToNode P =First(); //首节点出发 48 while (r--) 49 { 50 P = P->Succ; 51 } 52 return P->Data; 53 } 54 55 PtrToNode Find(int Element, int n, PtrToNode P) //查找目标元素E(从P(不包括)到P节点前n个元素) 失败时返回NULL 56 { 57 /*PtrToNode Ptr = P; 58 for (int i = 1; i < n + 1; i++) 59 { 60 Ptr = Ptr->Pred; 61 if (Ptr->Data == Element) 62 return Ptr; 63 } 64 return NULL;*/ 65 while (n--) 66 if (Element ==(P = P->Succ)->Data) return P; 67 return NULL; 68 } 69 70 PtrToNode InsertBefore(PtrToNode P, int Element) //将元素E当作P的前驱元插入 71 { 72 PtrToNode Ptr = (PtrToNode)malloc(sizeof(Node)); 73 Ptr->Data = Element; 74 Ptr->Succ = P; Ptr->Pred = P->Pred; 75 P->Pred = Ptr; Ptr->Pred->Succ = Ptr; 76 size++; 77 } 78 PtrToNode InsertAfter(PtrToNode P, int Element) //将元素E当作P的后继元插入 79 { 80 PtrToNode Ptr = (PtrToNode)malloc(sizeof(Node)); 81 Ptr->Data = Element; 82 Ptr->Pred = P; Ptr->Succ = P->Succ; 83 P->Succ = Ptr; Ptr->Succ->Pred = Ptr; 84 size++; 85 } 86 //复制 87 void CopyNodes(PtrToNode P, int n) 88 { 89 Init(); //创造一个新的首尾节点 90 while (n--) 91 { 92 InsertAsLast(P->Data); 93 P = P->Succ; 94 } 95 } 96 97 int Remove(PtrToNode P) //删除节点 98 { 99 int Element = P->Data; //备份数据 100 P->Pred->Succ = P->Succ; 101 P->Succ->Pred = P->Pred; 102 free(P); 103 size--; 104 return Element; //返回删除节点 105 } 106 107 int Delete() 108 { 109 /*PtrToNode P1, P2; 110 P1=P2=Header->Succ; 111 while (size--) 112 { 113 P2 = P1->Succ; 114 Remove(P1); //这里写错了 如果按照我的想法应该用free 115 P1 = P2; 116 } 117 free(Header); 118 free(Trailer);*/ //憨憨博主的做法 这部分写的有问题 remove 会对size进行改变 119 int OldSize = size; 120 while (size) 121 { 122 Remove(Header->Succ); 123 } 124 free(Header); 125 free(Trailer); 126 return OldSize; 127 } 128 129 int DeDuplicate() 130 { 131 if (size < 2) return 0; //平凡情况 132 int OldSize = size; 133 PtrToNode P = First(); 134 int r = 1; 135 while (Trailer!=(P=P->Succ)) 136 { 137 PtrToNode Q = Find(P->Data, r, P); 138 Q ? Remove(Q) : r++; //删除前面的元素 如果删除后面的会出错 因为此时P为NULL 139 } 140 return OldSize - size; 141 } 142 143 //有序列表 144 int Uniquify() //O(n) 145 { 146 /*if (size < 2) return 0; //平凡情况 147 int OldSize = size; 148 PtrToNode P1, P2; 149 P1 = First(); P2 = P1->Succ; 150 while (Trailer!=P2) 151 { 152 if (P1->Data == P2->Data) 153 { 154 Remove(P2); 155 P2 = P1->Succ; 156 } 157 else 158 { 159 P1 = P2; 160 P2 = P1->Succ; 161 } 162 } 163 return OldSize - size;*/ 164 //简化 165 if (size < 2) return 0; //平凡情况 166 int OldSize = size; 167 PtrToNode P1, P2; 168 P1 = First(); 169 while (Trailer!=(P2=P1->Succ)) 170 { 171 if (P1->Data!=P2->Data) 172 P1 = P2; 173 else 174 Remove(P2); 175 } 176 return OldSize - size; 177 } 178 179 PtrToNode Search(int Element, int n, PtrToNode P) //在P节点前的n个元素中 查找E 返回不大于E且秩最大的节点 为其它接口使用提供了方便 180 { 181 while (0<=n--) //等于0的情况 是为了处理在P节点前的n个元素中 没有查找到 返回P前第n+1个元素 182 { 183 if (Element >= (P = P->Pred)->Data) 184 break; 185 } 186 return P; 187 } 188 189 //排序算法 190 191 //选择排序 //O(n^2) 192 void SwapElement(PtrToNode P1, PtrToNode P2) //交换两个节点的元素 193 { 194 int Element = P1->Data; 195 P1->Data = P2->Data; 196 P1->Data = Element; 197 } 198 PtrToNode SelectMax(PtrToNode P, int n) 199 { 200 PtrToNode Max = P; 201 for (PtrToNode Cur = P; n > 1; n--) 202 { 203 if (Max->Data <= (Cur = Cur->Succ)->Data) //元素相同时也要返回后面的元素 204 Max = Cur; 205 } 206 return Max; 207 } 208 void SelectSort(PtrToNode P, int n) //将P后n个元素进行排序 209 { 210 PtrToNode head = P->Pred; 211 PtrToNode tail = P; 212 for (int i = 0; i < n; i++) tail = tail->Succ; 213 while (n>1) 214 { 215 //InsertBefore(tail, Remove(SelectMax(head->Succ, n))); 216 SwapElement(SelectMax(head->Succ, n),tail->Pred); 217 tail = tail->Pred; 218 n--; 219 /*优化 220 PtrToNode Max = SelectMax(head->Succ, n); 221 if (tail->Pred != Max) 222 SwapElement(Max, tail->Pred); 223 tail = tail->Pred; 224 n--;*/ 225 } 226 } 227 228 //插入排序 最好O(n) 最坏O(n^2) 229 void InsertionSort(PtrToNode P,int n) //从位置P开始 到之后的n个元素 230 { 231 for (int r = 0; r < n; r++) 232 { 233 InsertAfter(Search(P->Data, r, P), P->Data); 234 P = P->Succ; 235 Remove(P->Pred); 236 } 237 }
栈
标签:等于 学习 free 删除 算法 closed 改变 nbsp open
原文地址:https://www.cnblogs.com/57one/p/11409761.html