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 }

 

posted @ 2020-02-26 21:15  wsshub  阅读(293)  评论(0)    收藏  举报