#include #include #include #include typedef int elemtype;//定义结构体typedef struct node{ elemtype data; //数据域 struct node *next; //指针域}linklist,*prtnode;/*(1)create linklist表与顺序表不同,它是一种动态管理的存储结构,链表中的每个结点占用的存储空间不是预先分配,而是运行时系统根据需求而生成的,因此建立单链表从空表开始,每读入一个数据元素则申请一个结点,然后插在链表的尾部。*///算法描述跟随输入linklist *createlist(int n){ int i; int x; /* 初始化操作,定义phead(头指针,给他分配空间),定义尾指针ptail,定义跟随指针pfollow; linklist *phead ,*ptail,*pfollow; phead = new linklist; ptail = phead; pfollow = phead; ptail->next = NULL; // 一定要加空表 */ //构建头结点空间 linklist *phead; phead = new linklist; //构建尾结点,不断读入数->next=NULL; linklist *ptail; ptail = phead; ptail->next = NULL;//创建空表p->phead==NULL,应用程序不出错 //构造跟随指针 linklist *pfollow; pfollow = phead; //循环构建n个结点 for(i = 1; i<=n; i++) { cout<<"第"<>x; //不断取得空间,完成一个结点工作ptail ptail = new linklist; //h,f,t本身地址0x003708a8;next:0x00000000; data:NULL ptail->data = x; //h,f本身地址0x003708a8;next:0x00000000; data:NULL /t本身0x00370d80 next:0xcdcdcdcd data:NULL ptail->next = NULL; //h,f本身地址00x003708a8;next:0x00000000; data:NULL /t本身0x00370d80 next:0xcdcdcdcd data:5 //由于起初fh相互关联,告诉他们下个地址就是ptail pfollow->next = ptail; //h,f本身地址0x003708a8;next:0x00000000; data:NULL /t本身0x00370d80 next:0x00000000 data:5 //一个结点本身地址和next地址,将next地址传给本身,meaning将本身跳到该结点 pfollow = pfollow->next ; //*h,f本身0x003708a8,next:0x00370d80,data:null /t本身0x00370d80 next:0x00000000 data:5 } //h本身0x003708a8,next:0x00370d80,data:null /f,t 本身0x00370d80 next:0x00000000 data:5 return phead;}//倒置输入//先读数据,将数据插入linklist *createlist2(int n){ int i; linklist *p; linklist *phead; phead = new linklist;//头结点空间 phead->next=NULL; for(i=1;i<=n;i++) { //初始化新结点 p=new linklist; cout<<"第"<>p->data; //插入 p->next=phead->next; phead->next=p; } linklist *end; end=phead; /// if(end->next==NULL)// {//// phead=phead->next;// } // while(end->next!=NULL)// {// end=end->next;// }// end->next=phead; return phead; }//初始化一个空表void initlist(linklist *head){ head=new linklist; if(!head) { cout<<"分配失败"; exit(0); } head->next=NULL; //初始化头结点}/*(2)查找<一>查找元素按值查找:(从头指针开始)在链表中查找是否有结点等于给定值key的结点若有则返回首次找到值的存储位置,否则返回null算法思想:从开始结点出发,顺链表逐个结点的值和给定key做比较*/linklist *locate(const linklist *phead,elemtype &e) //phead是头结点,不是首结点 //or prtnode locate(prtnode phead,elemtype &e){ linklist *pindex; pindex = phead->next; //从头结点获得首结点 while(pindex!=NULL) //while(pindex!=NULL&&pindex->data!=x) { //{ pindex = pindex->next; } if(pindex->data==e) { cout<<"找到了"; break; } pindex = pindex->next; } //跳出循环访问到pindex为/*和head没关系 while里不能用做pindex->pnext!=NULL,错误很多:如因为若为空表,首结点data没有值,pindex->data访问出错如果第二个结点(不包括头结点),为空,while(pindex->pnext!=null)为真,没法对首结点进行访问;只能是while(pindex!=NULL)形式*/return pindex;}/*<二>查找元素按序号查找(从头指针开始)设单链表长度为length,要查找第i个结点算法思想从头结点开始扫描.用j做已扫描的计数器,当p扫描下一个结点时,j++;p的初值指向头结点,j=0当j==i,,指针p所指就是第i个结点*/linklist *findi(linklist *phead,elemtype i_base){ int j_add; linklist *pindex; pindex = phead->next; j_add = 1; while(pindex!=NULL) { //while(p && jnext; pindex = pindex->next; //} j_add++; } return pindex;}/*(3)插入元素<定值后插一>类似于查找运算,单链表的插入运算也可分两种方式来处理,一种按给定值插入另一种按给定序号插入,根据给定的问题而定。下面主要讨论按给定值来处理。*/linklist *insertlist( linklist *phead,elemtype compare,elemtype insert){ linklist *ptem; linklist *pinsert; //初始化一个结点,赋值 pinsert = new linklist; pinsert->data = insert; pinsert->next = NULL; ptem = phead->next; if(NULL==ptem) //空表直接插入 { phead->next = pinsert; } else { while( ptem->next!=NULL && ptem->data!=compare ) //条件要注意 ptem && ptem->next 能保证链表有两个元素 ptem=ptem->next; //两种推出情况end退出,找到推出 if(ptem->data==compare) //在此访问会出问题,处理找到推出 { pinsert->next = ptem->next; //注意交换次序 ptem->next = pinsert; } else //处理end推出 { ptem->next=pinsert; } } return phead;}//插入按值<前插二>linklist *insertlist2(linklist *phead,elemtype compare,elemtype insert){ linklist *ptem; linklist *ptemnext; //初始化一个结点,赋值 linklist *pinsert; pinsert = new linklist; pinsert->data = insert; pinsert->next = NULL; ptem=phead->next; //链表为空时做前插 if(NULL==ptem) { phead->next = pinsert; } else { while( ptem && ptem->next) //限制存在两个结点,//ptemnext,和ptem { ptemnext=ptem->next; if(ptem->data==compare) //当compare首次出现在ptem时做前插 { phead->next=pinsert; pinsert->next=ptem; break; } if(ptemnext->data==compare) //根据ptemnext比较做前插 { ptem->next=pinsert; pinsert->next=ptemnext; break; } ptem=ptem->next; //下一个,指针后移 ptemnext=ptemnext->next; } //限制一个结点,做前插 if(ptem->data==compare &&ptem->next==NULL) { phead->next=pinsert; pinsert->next=ptem; } else //都没有匹配时做最后一个插入 { ptem->next=pinsert; pinsert->next=ptemnext; } } return phead;}//插入前插按位置查找//1data=e; insert->next=NULL; p=head; j=0; while(p&& jnext; ++j; } if( !p || j>postion-1) //对不和参数,,空表一个元素是 return 0; insert->next=p->next; p->next=insert;}/*单链表删除*///按值删除linklist *dellist(linklist *phead,elemtype delelem){ linklist *ptem; linklist *ptemnext; ptem=phead->next; if(ptem==NULL) { cout<<"the link is empty/n"; return phead; } while(ptem!=NULL && ptem->next!=NULL) //限制两个结点 { ptemnext=ptem->next; if(ptemnext->data==delelem) { ptem->next=ptemnext->next; } ptem=ptem->next; } return phead;}//按序号删除linklist *dellist2(linklist *phead,int i){ linklist *pfollow; linklist *ptem; int j; //j++确定删除的元素次序 pfollow=phead->next; if(i==1) //限制结点为首结点 { phead->next=pfollow->next; //phead=pfollow ; } else //其余结点 { j=1; while( pfollow!=NULL && jnext; j++; } ptem=pfollow->next; //删除元素 pfollow->next=ptem->next; delete ptem; //不要忘记释放指针 } return phead;}//1next&&jnext; //p->next为p的前驱 j++; } if( !(p->next)||j>pos-1) { cout<<"error"; return false; } q=p->next; p->next=p->next->next; delete q; return true;}//()输出数据int printlist(const linklist *phead){ linklist *ptemp; ptemp = phead->next; while(ptemp) //while(ptemp!=NULL) 更安全 { cout<data<<" "; ptemp = ptemp->next; } cout<next; j=1; while(p && jnext; } if(postion==j) { e=p->data; } else { cout<<"不存在该元素/n";; return false; } return true; /*方法二: if ( !p || j>pos ) return FALSE; 链表中不存在第 pos 个结点 j>pos??? e = p->data; 取到第 pos 个元素 return TRUE; */ }//置空linklist *empty(linklist *phead){ linklist *ptem; linklist *ptem_release; ptem = phead->next; if(ptem==NULL) { return phead; } while(ptem) { ptem_release=ptem; ptem=ptem->next; delete ptem_release; } delete ptem; phead->next=NULL; return phead;}int lengthlist(const linklist *phead){ int length=0; linklist *ptem; ptem=phead->next; while(ptem) { ptem=ptem->next; length++; } return length;}//销毁void destorylist(linklist *phead){ linklist *ptem; linklist *ptem_release; ptem = phead->next; //删除非头结点,释放内存 while(ptem) { ptem_release=ptem; ptem=ptem->next; delete ptem_release; } //释放头结点 delete phead; }/*void initlist(linklist *head);linklist *createlist(int n);linklist *createlist2(int n);linklist *locate(const linklist *phead,elemtype &e);linklist *findi(linklist *phead,elemtype i_base);linklist *insertlist( linklist *phead,elemtype compare,elemtype insert);linklist *insertlist2(linklist *phead,elemtype compare,elemtype insert);linklist *dellist(linklist *phead,elemtype delelem);linklist *dellist2(linklist *phead,int i);void printlist(const linklist *phead);linklist *empty(linklist *phead)int lengthlist(const linklist *phead)void destorylist(linklist *phead);bool getelem(linklist *head,int postion,elemtype &e)*/void information(){ printf(" ----------------------------------------/n"); printf(" | Test 链表应用测 |/n"); printf(" |__ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|/n"); printf(" | 1. 初始化化链表 |/n"); printf(" | 2. 查询数据是否在表中 |/n"); printf(" | 3. 查询表中数据的号码 |/n"); printf(" | 4. 前插按值数据 |/n"); printf(" | 5. 后插按值数据 |/n"); printf(" | 6. 删除指定位置数据 |/n"); printf(" | 7. 删除所选数据 |/n"); printf(" | 8. 打印链表数据 |/n"); printf(" | 9. 将已有链表置空 |/n"); printf(" | 10. 返回表中的数据个数 |/n"); printf(" | 11. 彻底销毁整个表 |/n"); printf(" | 12. 得到某个数据 |/n"); printf(" | 0. 退出程序 |/n"); printf(" --------------------------------------- /n"); printf(" /n/n"); printf(" <按99重新打印帮助说明>/n");}int mainwhile(void){ linklist test; linklist *head; int n=0; int length=0; int compare; int insert; int del; int finde; int base; int i_base; int getelemt; information(); cout<<"请输入您选择的号码___"; cin>>base; while(1) { switch (base) { case 1: cout<<"请输入数据总数____"; cin>>n; head=createlist(n); break; case 2: if(n==0) { cout<<"请先初始化表"; break; } cout<<"请输入要查询的数据__"; cin>>finde; head=locate(head,finde); break; case 3: if(n==0) { cout<<"请先初始化表"; break; } cout<<"请输入要查询的序列___"; cin>>i_base; head=findi(head,i_base); break; case 4: if(n==0) { cout<<"请先初始化表"; break; } cout<<"请输入要插入的数据__"; cin>>insert; cout<<"请选定在哪个数据前插入__"; cin>>compare; head=insertlist2(head, compare, insert); break; case 5: if(n==0) { cout<<"请先初始化表"; break; } cout<<"请输入要插入的数据__"; cin>>insert; cout<<"请选定在哪个数据后插入__"; cin>>compare; head=insertlist(head, compare, insert); break; case 6: if(n==0) { cout<<"请先初始化表"; break; } cout<<"请输入要删除数据的位置__"; cin>>i_base; head=dellist2(head, i_base); break; case 7: if(n==0) { cout<<"请先初始化表"; break; } cout<<"请输入要删除的数据"; cin>>del; head=dellist2(head,del); break; case 8: if(n==0) { cout<<"请先初始化表"; break; } cout<<"表的内容为/n"; printlist(head); break; case 9: if(n==0) { cout<<"请先初始化表"; break; } n=0; empty(head); printlist(head); information(); break; case 10: if(n==0) { cout<<"请先初始化表"; break; } length=lengthlist(head); cout<<"表中的数据个数为:/n"; cout<>i_base; getelem(head,i_base,getelemt); cout<>base; } return 1;}void main(){ mainwhile(); }