C++模拟链表

C++模拟链表

简易模拟链表,工厂设计模式。。

注意:请不要在操作时产生环状链表,会造成输出链表时陷入无限循环。

  1 #include <iostream>
  2 #include <string>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <cstring>
  6 #include <vector>
  7 #include <map>
  8 #include <algorithm>
  9 #define range(i,a,b) for(int i=a;i<=b;++i)
 10 #define rerange(i,a,b) for(int i=a;i>=b;--i)
 11 #define LL long long
 12 #define CLS(arr) memset(arr,0,sizeof(arr))
 13 using namespace std;
 14 inline void line(){range(i,0,40)cout<<(i==40?'\n':'=');}//内置画线函数
 15 struct node{
 16     /*
 17      * 链表节点
 18      */
 19     int value;
 20     node *next;
 21     node(int val=0){value=val;next=NULL;}
 22 };
 23 class linklist{
 24     /*
 25      * 链表类
 26      */
 27 private:
 28     node* head;
 29     unsigned long len;
 30 public:
 31     linklist(unsigned long l=1):len(l){
 32         /*
 33          * 链表构造,默认链表长度为1,传入其他参数可扩充。
 34          * 模仿vector性质,未设置值的位置默认为0
 35          */
 36         head=new node;
 37         if(len==1){head->next=NULL;}
 38         else{
 39             node *tmp=head;
 40             range(i,2,len){
 41                 head->next=new node;
 42                 head=head->next;
 43             }
 44             head->next=NULL;
 45             head=tmp;
 46         }
 47     }
 48     void combine(unsigned long l){len=l;}
 49     void insert(unsigned long index,int value){
 50         /*
 51          * 在index后面插入一个value值的节点。
 52          */
 53         node *tmp=head;
 54         if(index>=len){cout<<"list index out of range"<<endl;return;}
 55         while(index--)head=head->next;
 56         node *store=head->next;
 57         head->next=new node(value);
 58         head->next->next=store;
 59         head=tmp;
 60         ++len;
 61     }
 62     void pop(unsigned long index){
 63         /*
 64          * 删除index位置的节点。
 65          */
 66         node *tmp=head;
 67         if(index>=len){cout<<"list index out of range"<<endl;return;}
 68         --len;
 69         if(!index){
 70             head=head->next;
 71             delete(tmp);
 72             return;
 73         }
 74         while((index--)-1)head=head->next;
 75         node *pos=head->next->next;
 76         delete(head->next);
 77         head->next=pos;
 78         head=tmp;
 79     }
 80     void pop(node* pos){
 81         /*
 82          * 删除指针为pos的节点。
 83          * 此函数为模拟迭代器。
 84          */
 85         node *tmp=head;
 86         --len;
 87         if(head==pos){
 88             head=head->next;
 89             delete(tmp);
 90             return;
 91         }
 92         while(head->next!=pos)head=head->next;
 93         node *store=head->next->next;
 94         delete(head->next);
 95         head->next=store;
 96         head=tmp;
 97     }
 98     void setvalue(unsigned long index,int value){
 99         /*
100          * 改变index位置的值为value
101          */
102         node *tmp=head;
103         if(index>=len){cout<<"list index out of range"<<endl;return;}
104         while(index--)head=head->next;
105         head->value=value;
106         head=tmp;
107     }
108     node* begin(){
109         /*
110          * 返回头节点地址
111          */
112         return head;
113     }
114     node* end(){
115         /*
116          * 返回尾节点地址
117          */
118         node *tmp=head;
119         while(tmp->next)tmp=tmp->next;
120         return tmp;
121     }
122     unsigned long length(){ return len; }//输出链表长度
123     void show(){
124         /*
125          * 输出整个链表
126          */
127         node *tmp=head;
128         while(head){
129             cout<<head->value<<" ";
130             head=head->next;
131         }
132         cout<<endl;
133         head=tmp;
134     }
135 };
136 class factory{
137     /*
138      * 链表工厂:
139      * 创建链表、选择链表、合并两个链表
140      * 默认新增同名链表覆盖原链表
141      */
142 private:
143     map<string,linklist*>data;
144 public:
145     int MENU(){
146         /*
147          * 工厂菜单
148          */
149         unsigned int choice;
150         line();
151         cout<<"1.创建链表"<<endl;
152         cout<<"2.选择链表"<<endl;
153         cout<<"3.合并链表"<<endl;
154         cout<<"0.退出"<<endl;
155         line();
156         cout<<"选择:";cin>>choice;
157         if(choice>3){cout<<"menu index out of range"<<endl;return -1;}
158         else return choice;
159     }
160     int listmenu(){
161         /*
162          * 链表操作菜单
163          */
164         unsigned int choice;
165         line();
166         cout<<"1.插入"<<endl;
167         cout<<"2.删除"<<endl;
168         cout<<"3.更改"<<endl;
169         cout<<"4.去奇"<<endl;
170         cout<<"0.退出"<<endl;
171         line();
172         cout<<"选择:";cin>>choice;
173         if(choice>4){cout<<"menu index out of range"<<endl;return -1;}
174         else return choice;
175     }
176     void MAIN(){
177         /*
178          * 链表工厂的主函数
179          */
180         int tmp;
181         while((tmp=MENU())&&tmp){
182             switch (tmp){
183                 case 1:create();break;
184                 case 2:select();break;
185                 case 3:combine();break;
186                 case -1:break;
187             }
188         }
189     }
190     void create(){
191         /*
192          * 创建链表。
193          */
194         string name;
195         unsigned long len;
196         cout<<"链表命名:";cin>>name;
197         cout<<"链表长度:";cin>>len;
198         data[name]=new linklist(len<=1?1:len);
199     }
200     void select(){
201         /*
202          * 选择链表进入链表菜单。
203          */
204         string name;int cnt=0;
205         line();
206         map<string,linklist*>::iterator iter;
207         for(iter=data.begin();iter!=data.end();++iter)cout<<iter->first<<((++cnt)%4?' ':'\n');
208         if(cnt%4)cout<<endl;
209         line();
210         cout<<"请选择如上例举出的链表名:";cin>>name;
211         if(data[name]==NULL){cout<<"不存在该链表!"<<endl;return;}
212         while((cnt=listmenu())&&cnt){
213             unsigned long index;int value;
214             switch (cnt){
215                 case 1:cout<<"输入位置、值:";cin>>index>>value;data[name]->insert(index,value);break;
216                 case 2:cout<<"输入位置:";cin>>index;data[name]->pop(index);break;
217                 case 3:cout<<"输入位置、值:";cin>>index>>value;data[name]->setvalue(index,value);break;
218                 case 4:
219                     node *begin=data[name]->begin(),*end=data[name]->end(),*pos;
220                     for(pos=begin;pos!=end;pos=pos->next)if(pos->value&1)data[name]->pop(pos);
221             }
222             data[name]->show();
223         }
224     }
225     void combine(){
226         /*
227          * 将两链表首尾结合。
228          */
229         string name1,name2;int cnt=1;
230         line();
231         map<string,linklist*>::iterator iter;
232         for(iter=data.begin();iter!=data.end();++iter)cout<<iter->first<<((++cnt)%4?' ':'\n');
233         if(cnt%4)cout<<endl;
234         line();
235         cout<<"请选择如上例举出的两个链表名:";cin>>name1>>name2;
236         if(data[name1]==NULL||data[name2]==NULL){cout<<"不存在链表!"<<endl;return;}
237         node *end=data[name1]->end(),*begin=data[name2]->begin();
238         end->next=begin;
239         data[name1]->combine(data[name1]->length()+data[name2]->length());
240         data[name1]->show();
241     }
242 };
243 int main(int argc, char *argv[]){
244     factory MM;//创建链表类工厂
245     MM.MAIN();//进入工厂主函数
246     return 0;
247 }

猜你喜欢

转载自www.cnblogs.com/Rhythm-/p/9254934.html
今日推荐