3.0列表
列表的基本实现,含选择排序,插入排序,归并排序(有问题,未解决)
双链表实现归并排序,在测试案例中给出了错误的排序结果。看了好久代码觉得逻辑没错啊,而且代码也是照着书上敲的。头疼......
1 #include<iostream> 2 using namespace std; 3 struct ListNode{ 4 5 int data; 6 ListNode *pred; 7 ListNode *succ; 8 ListNode(){ }//用于header和trailer初始化,如果没有这一句后面的init() 会报错 9 ListNode(int e,ListNode* p=NULL,ListNode *s=NULL):data(e),pred(p),succ(s){} 10 }; 11 class List{ 12 public: 13 int size; 14 ListNode *header; 15 ListNode *trailer; 16 List(){ 17 header=new ListNode; 18 trailer=new ListNode; 19 header->succ=trailer;header->pred=NULL; 20 trailer->succ=NULL;trailer->pred=header; 21 size=0; 22 23 } 24 25 ListNode* find(int e,int n,ListNode *p){//在p的n个前缀中查找e,并返回指向e的指针 26 while(0<n--) 27 if(e==(p=p->pred)->data) 28 return p; 29 30 return NULL; 31 } 32 33 ListNode* insertAsPred(int e,ListNode* p){//e当作p的前缀插入 34 ListNode* x=new ListNode(e,p->pred,p); 35 p->pred->succ=x; 36 p->pred=x;//顺序不能改变 37 size++; 38 return x; 39 40 } 41 ListNode* insertAsSucc(int e,ListNode* p){//e作为p的后缀插入 42 ListNode *x=new ListNode(e,p,p->succ); 43 p->succ->pred=x; 44 p->succ=x; 45 size++; 46 return x; 47 } 48 int remove(ListNode* p){ 49 int e=p->data; 50 p->pred->succ=p->succ; 51 p->succ->pred=p->pred; 52 53 delete p; 54 p=NULL; 55 size--; 56 return e; 57 } 58 int clear(){ 59 int n=size; 60 int oldsize=size; 61 while(n--)//!!!!!!原来这里是size--,改变了size,这里应该是次数控制,不应该改变size! 62 remove(header->succ);//写成size--,析构函数没办法正常运行,返回一个奇怪的数,且运行时间较长 63 return oldsize;//debug技巧要学一些,找半天 ,课本也不是这么写的,果然自己敲容易出bug... 64 } 65 ~List() 66 { 67 68 clear(); 69 delete header; 70 header=NULL; 71 delete trailer; 72 trailer=NULL; 73 } 74 int deduplicate(){ 75 if(size<2)return 0; 76 int oldsize=size; 77 ListNode *p=header; 78 int r=0; 79 ListNode *q=NULL; 80 while((p=p->succ)!=trailer) 81 {q=find(p->data,r,p); 82 q?remove(q):r++; 83 } 84 85 return oldsize-size; 86 } 87 88 int uniquify(){//有序列表唯一化 89 if(size<2)return 0; 90 int oldsize=size; 91 ListNode *p=header->succ; 92 ListNode *q; 93 while(trailer!=(q=p->succ)) 94 {if(p->data==q->data) 95 remove(q); 96 else 97 p=q; 98 } 99 return oldsize-size; 100 } 101 ListNode* search(int e,int n,ListNode *p){//有序列表查找 102 103 while(0<=n--)//条件为0<n--时出错 104 if(e>=((p=p->pred)->data)) 105 break;//找到不大于e的最大元素 106 107 return p; 108 } 109 110 void insertionSort(ListNode *p,int n){//对起始于p的后n个元素排序 111 for(int i=0;i<n;i++){ 112 113 insertAsSucc(p->data,search(p->data,i,p));//找到p的前缀中(p的前缀假设已经排列好)不大于p->data的最大元素,将p作为后缀插入 114 // 列表将呈现升序排列 115 116 p=p->succ; 117 remove(p->pred); 118 } 119 } 120 121 void selectionSort(ListNode *p,int n){//对起始于p的后n个元素排序 122 123 ListNode *temp=NULL,*max=NULL; 124 ListNode *header=p->pred,*tail=p; 125 for(int i=0;i<n;i++) 126 tail=tail->succ;//待排序区间为(header,tail) 127 while(n>1){//找到前缀中最大的元素,放到后缀 128 129 temp=max=header->succ;//注意为什么不用p而用header->succ,p随时可能因为是最大元素而被改变位置 130 //用header->succ可一直间接访问首元素 131 for(int i=1;i<n;i++)//找到起始于位置p的后n个元素的最大元素的位置 132 { 133 temp=temp->succ; 134 if((temp->data)>=(max->data)) 135 max=temp; } 136 137 insertAsPred(remove(max),tail); 138 tail=tail->pred;//更新无序向量末元素 139 n--; 140 } 141 } 142 /*void mergeSort(ListNode* &p,int n){//对起始于p的后n个元素排序 143 144 if(n<2)return; 145 int m=n>>1; 146 ListNode *q=p; 147 for(int i=0;i<m;i++) q=q->succ; 148 mergeSort(p,m); 149 mergeSort(q,n-m); 150 merge(p,m,q,n-m); 151 152 } 153 void merge(ListNode *&p,int n,ListNode *q,int m){ 154 ListNode *pp=p->pred; 155 while(m>0) 156 if((n>0)&&(p->data<=q->data)) 157 { if(q==(p=p->succ))//为什么这个判断条件是必要的 158 // if((p=p->succ)&&n==1) 159 break;//当p的最后一元素比较完毕,即可退出循环,因为已经归并完毕 160 n--; 161 } 162 else//当p->data大于q->data 163 { 164 insertAsPred(remove((q=q->succ)->pred),p) ;//事实上当p没有元素时已经退出循环 165 m--; 166 } 167 p=pp->succ; 168 169 }*/ 170 void print(){ 171 ListNode *p=NULL; 172 p=header->succ; 173 174 while(trailer!=p) 175 { 176 cout<<p->data<<" "; 177 p=p->succ; 178 } 179 cout<<endl<<"size:"<<size<<endl<<endl; 180 181 182 } 183 }; 184 185 int main(){ 186 List data; 187 ListNode *p=data.header; 188 int test[16]={9,9,25,3,71,45,62,71,20,21,25,86,55,125,1,21}; 189 for(int i=0;i<16;i++) 190 { 191 data.insertAsSucc(test[i],p); 192 p=p->succ;} 193 194 data.print(); 195 196 p=data.header; 197 198 //测试选择排序 ,通过 199 //data.selectionSort(p->succ,data.size); 200 //测试插入排序,通过 201 data.insertionSort(p->succ,data.size); 202 //测试归并排序,有问题 203 //data.mergeSort(p->succ,data.size); 204 data.print(); 205 206 data.deduplicate(); 207 data.print(); 208 209 210 return 0; 211 }

浙公网安备 33010602011771号