关于链表的各种细节问题

来源:互联网 发布:潜水是什么意思网络语 编辑:程序博客网 时间:2024/04/28 19:53

链表由于和指针密切相关,不免会出现各种关于指针方面的问题,处理不当就会导致bug众多,可能是找不到该指针,可能是数据被覆盖……因此在写程序的开头,就需要先定好实现的大体方法,通过图的方式先把算法描述一遍再开始写程序。


一、关于c和c++的使用问题:

如果准备用C写,就尽量避免使用C++封装的部分,如果准备用C++写,就尽量少用malloc、free等表达形式

如链表中,申请新的内存空间时用list l1=(list)malloc(sizeof(struct element))的形式,如果list中有string类型的变量 在cin时候会报错,因为C无法明确知道string的大小,因此开辟内存空间的时候会出现Bug。


二、关于排序的问题:

对于链表的排序涉及到了两个结构的交换。

1.若采用交换指针的方式,则该名称指代的地址不变,位置发生改变。即:

这种情况下tail位于head前面,因此无法进行排序算法的实现。

2.可以采取交换数据的方式,但是如果进行大数据量的结构交换,则该方法过于繁杂。

3.查找该节点的前一个节点可以写一个previous函数,通过函数调用查找该节点,还可以使用双向链表进行查找。

4.链表中实现选择排序的一个较好办法是构造一个新链表,将已排序内容放入新的链表,最后再将新链表的表头放入原始链表,通过这种方法实现排序。


下面为使用链表的图书管理系统的源代码:

#include<stdlib.h>#include<iostream>#include<string>using namespace std;typedef struct element* list;typedef struct element* position;struct element{string ID;string NAME;float price;struct element* Next;};void input(list List){                                //输入数据while(1){position temp;temp=new element();cin>>temp->ID; if(temp->ID=="finish")break;                  //当遇到finish结束cin>>temp->NAME; cin>>temp->price;position p=List;while(p->Next!=NULL){p=p->Next;}temp->Next=NULL;p->Next=temp;}}void output(list l){                                 //输出数据position p;p=l->Next;if(p==NULL)cout<<"无法查到数据!"<<endl;while(p!=NULL){cout<<p->ID<<" "<<p->NAME<<" "<<p->price<<endl;p=p->Next;}}position previous(list l1,position p){                //查找前一个位置position temp=new element();temp=l1;while(temp->Next!=p){temp=temp->Next;}return temp;}void find_name(string NAME,list l){                 //根据名称查找position p;p=l->Next;while(p!=NULL){if(p->NAME==NAME){cout<<p->ID<<" "<<p->NAME<<" "<<p->price<<endl;}p=p->Next;}}position find_id(string ID,list l){                     //根据ID查找position p;p=l->Next;while(p->ID!=ID&&p!=NULL){p=p->Next;}if(p==NULL)printf("查找错误!\n");else cout<<p->ID<<" "<<p->NAME<<" "<<p->price<<endl;return p;}position mid(list l1,position head,position tail){       //快排的具体实现步骤position Flag=l1->Next;float flag=head->price;position p=new element();p->ID=head->ID;p->NAME=head->NAME;p->price=head->price;while(head!=tail){position temp=new element();  while(head!=tail&&tail->price<=flag){tail=previous(l1,tail);}head->NAME=tail->NAME;head->ID=tail->ID;head->price=tail->price;while(head!=tail&&head->price>=flag){head=head->Next;}tail->ID=head->ID;tail->NAME=head->NAME;tail->price=head->price;}head->ID=p->ID;head->NAME=p->NAME;head->price=p->price;while(Flag->ID!=p->ID){Flag=Flag->Next;}return Flag;}void quick_sort(list l1,position head,position tail){      //快排的递归过程if(head!=tail){position middle=mid(l1,head,tail);quick_sort(l1,head,previous(l1,middle));   quick_sort(l1,middle->Next,tail);}}list select_sort(list l1){//选择排序list l2=(list)malloc(sizeof(struct element));       //排序链表的头指针position Tail;  //排序链表的尾指针position p;//用于比较的指针position pre;//最大节点的前一节点position max;//指向最大的节点l2->Next=NULL;while(l1->Next!=NULL){for(p=l1->Next,max=l1->Next;p!=NULL;p=p->Next){           //挑选最大节点if(p->price>max->price){max=p;pre=previous(l1,p);}}if(l2->Next==NULL){                                      //将最大节点放入新链表末尾l2->Next=max;Tail=max;}else {Tail->Next=max;Tail=max;}if(max==l1->Next){ //在原链表中去掉该节点l1->Next=l1->Next->Next;}else {pre->Next=max->Next;}if(l2->Next!=NULL){                                       Tail->Next=NULL;//新链表末尾置空}}l1=l2;return l1;}int main(){list l1; l1 = new element();   //此处不能用(list)malloc(sizeof(struct element));否则使用string时会报错l1->Next=NULL;while(1){printf("--------------菜单-----------------\n");printf("--------1.输入图书信息-------------\n");printf("--------2.输出图书信息-------------\n");printf("--------3.查找图书信息-------------\n");printf("--------4.对图书信息进行排序-------\n");printf("--------5.退出系统-----------------\n");int c;cin>>c;switch(c){case 1:{cout<<"请输入数据,并以finish表示结束。输入格式为:ISBN 名称 价格  "<<endl;input(l1);}break;case 2:output(l1);break;case 3:{cout<<"按ID查找请按1,按书名查找请按2:"<<endl;int x;cin>>x;if(x==1){printf("请输入该书的ID号:");string id;cin>>id;find_id(id,l1);}else if(x==2){printf("请输入该书的书名:");string name;cin>>name;find_name(name,l1);}else {cout<<"输入错误!"<<endl;}}break;case 4:                                 {cout<<"采用快速排序请按1,采用选择排序请按2"<<endl;int y;cin>>y;if(y==1){position head=l1->Next;position tail=l1->Next;while(tail->Next!=NULL)tail=tail->Next;quick_sort(l1,head,tail);}else if(y==2){l1=select_sort(l1);}else {cout<<"输入错误!"<<endl;} }break;case 5:exit(0);break;}}}


0 0