数据结构——链式表中基本操作的实现


/*
链式表中基本操作的实现
2018.04.12
*/

#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>

using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;

typedef struct{
    char no[20];
    char name[30];
    double price;
}BOOK;

typedef struct LNode{
    BOOK data;  //结点数据
    struct LNode *next; //节点的指针域
}LNode,*LinkList;

//---------------------------------------------------------------------------------------------
//单链表的初始化
//算法步骤:
//1.生成新结点作为头结点,用头指针L指向头结点;
//2.头结点的指针域置空;
Status InitList(LinkList &L){
    //构造一个空的单链表L
    L=new LNode;
    L->next=NULL;
    return OK;
}

//---------------------------------------------------------------------------------------------
//单链表的取值
//算法步骤:
//1.用指针p指向首元结点,用j做计数器初赋值为1;
//2.从首元结点开始一次顺着链域next向下访问;只有指向当前结点的指针p不为空(NULL),并且没有到达序号为i的结点时,则循环执行以下操作:
//  p指向下一结点
//  计数器j相应加一
//  退出循环时,若指针p为空或者计数器j>i,说明指定的序号i值不合法(i大于表长n或i小于等于0),取值失败返回ERROR;否则取值成功,此时j=i,p指向的结点就是要找的第i个结点,用参数e保存当前结点的数据域,返回OK;

Status GetElem(LinkList L,int i,BOOK &e){
    //在带头结点的单链表L中根据序号i获取元素的值,用e返回L中的第i个数据元素的值
    int j=1;    //初始化,计数器j初赋值为1
    LNode *p;
    p=L->next;  //初始化,p指向首元结点
    while(p&&j<i){
        ++j;        //计数器j相应加1
        p=p->next;  //p指向下一个结点
    }
    if(!p||j>i)
        return ERROR;   //i值不合法,i>n或i<=0
    e=p->data;      //取第i个结点的数据域
    return OK;
}

//---------------------------------------------------------------------------------------------
//单链表的按值查找
//算法步骤:
//1.用指针p指向首元结点;
//2.从首元结点开始依次顺着链域next向下查找,只要指向当前结点的指针p不为空,并且p所指向结点的数据域不等于给定值e,则循环执行:p指向下一结点;
//3.返回p;若成功,则返回结点的地址值;若失败,p的值为NULL;

//根据图书的书名查找
LNode *LocateElemOfname(LinkList L,BOOK e){
    //在带头结点的单链表L中查找值为e的元素
    LinkList p;
    p=L->next;  //初始化,p指向首元结点
    //while(p&&p->data!=e){ //顺链域往后扫描,直到p为空或p所指向结点的数据域等于e
    while(p&&strcmp(p->data.name,e.name)!=0){
        p=p->next;  //p指向下一个结点
    }
    return p;   //查找成功返回为e的结点地址p,查找失败p为NULL
}

//根据图书的IBSN码查找
LNode *LocateElemOfIBSN(LinkList L,BOOK e){
    LinkList p;
    p=p->next;
    while(!p&&strcmp(p->data.no,e.no)!=0){
        p=p->next;
    }
    return p;
}

//---------------------------------------------------------------------------------------------
//单链表的插入
//算法步骤:
//1.查找结点ai-1并由指针p指向该结点;
//2.生成一个新的结点;
//3.将新的结点*s的数据域置为e;
//4.将新的结点*s的指针域指向结点ai;
//5.将结点*p的指针域指向新的结点*s;
Status ListInsert(LinkList &L,int i,BOOK e){  //在第i个前插入
    //在带头结点的单链表L中第i个位置插入值e的新结点
    LinkList p;
    int j=0;
    p=L;
    while(p&&(j<i-1)){
        p=p->next;
        ++j;        //查找第i-1个结点,p指向该结点
    }
    if(!p||(j>i-1))
        return ERROR;   //i>n+1 或 i<1
    LinkList s=new LNode;   //创建新结点*s
    s->data=e;  //将结点*s的数据域置为e
    s->next=p->next;    //将结点*s的指针域指向结点ai
    p->next=s;  //将结点*p的指针域指向结点*s
    return OK;
}

//---------------------------------------------------------------------------------------------
//单链表的删除
//算法步骤:
//1.查找结点ai-1并由指针p指向该结点;
//2.临时保存待删除结点ai的地址在q中,已备释放;
//3.将结点*p的指针域指向ai的直接后继结点;
//4.释放结点ai的空间;
Status ListDelete(LinkList &L,int i){  //在第i个后插入
    //再带头结点的单链表L中,删除第i个元素
    int j=0;
    LinkList p;
    p=L;
    while((p->next)&&(j<i-1)){ //查找第i-1个结点,p指向该结点
        ++j;
        p=p->next;
    }
    if(!(p->next)||(j>i-1)) //当i>n或i<1时,删除位置不合理
        return ERROR;
    LinkList q;
    q=p->next;  //临时保存被删结点的地址以备释放
    p->next=q->next;    //改变删除结点前驱结点的指针域
    delete q;   //释放删除结点的空间
    return OK;
}

//---------------------------------------------------------------------------------------------
//前插法创建单链表
//算法步骤:
//1.创建一个只有头结点的空链表;
//2.根据待创建链表包括的元素的个数n,循环n次执行以下操作:
//  生成一个新结点;
//  输入元素值赋给新结点*p的数据域
//  将新结点*p插入到头结点之后
void CreateList_H(LinkList &L,int n){
    L=new LNode;    //先建立一个带头结点的空链表
    L->next=NULL;   
    for(int i=0;i<n;++i){
        LinkList p=new LNode;   //生成新结点*p
        cout<<"No:"<<i+1<<endl;
        cin>>p->data.no>>p->data.name>>p->data.price;   //输入元素值赋值给新结点*p的数据域
        p->next=L->next;    
        L->next=p;  //将新结点*p插入到头结点之后
    }
}

//---------------------------------------------------------------------------------------------
//后插法创建单链表
//算法步骤:
//1.创建一个只有头结点的空链表;
//2.尾指针r初始化,指向头结点;
//3.根据创建链表包括的元素个数n,循环n次执行以下操作;
//  生成一个新结点*p;
//  输入元素值赋给新结点*p的数据域;
//  将新结点*p插入到尾结点*r之后;
//  尾指针r指向新的尾结点*p;
void CreateList_R(LinkList &L,int n){
    L=new LNode;    //先建立一个带头结点的空链表
    L->next=NULL;
    LinkList r;
    r=L;    //尾指针r指向头结点
    for(int i=0;i<n;++i){
        LinkList p=new LNode;   //生成新结点
        cout<<"No:"<<i+1<<endl;
        cin>>p->data.no>>p->data.name>>p->data.price;   //输入元素值赋值给新结点*p的数据域
        p->next=NULL;   
        r->next=p;  //将新结点*p插入尾结点*r之后
        r=p;    //r指向新的尾结点*p
    }
}

//-----------------------------------------------------------------------------------------
//删除顺序表
Status DeleteList(LinkList &L){
    delete L;
    return OK;
}

int main(){
    int option;
    LinkList L=new LNode;
    while(1){
        system("pause");
        system("CLS");
        cout<<endl<<"图书管理系统"<<endl;
        cout<<"---------------------------------"<<endl;
        cout<<"1.链式表初始化"<<endl;
        cout<<"2.使用前插法插入数据"<<endl;
        cout<<"3.使用后插法插入数据"<<endl;
        cout<<"4.插入数据"<<endl;
        cout<<"5.根据IBSN查找"<<endl;
        cout<<"6.根据书名查找"<<endl;
        cout<<"7.取出数值"<<endl;
        cout<<"8.显示数据"<<endl;
        cout<<"9.删除数据"<<endl;
        cout<<"10.删除链式表"<<endl;
        cout<<"0.退出"<<endl;
        cout<<"---------------------------------"<<endl;
        cout<<"Please input option:";
        cin>>option;
        BOOK e;
        LNode *str;
        int tmp;
        switch(option){
        case 1:
            if(InitList(L))
                cout<<"1.Success!"<<endl;
            else
                cout<<"1.Error!"<<endl;
            break;
        case 2:
            cout<<"请输入需要插入的结点数量:";
            cin>>tmp;
            CreateList_H(L,tmp);
            cout<<"2.操作完成"<<endl;
            break;
        case 3:
            cout<<"请输入需要插入的结点数量:";
            cin>>tmp;
            CreateList_R(L,tmp);
            cout<<"3.操作完成"<<endl;
            break;
        case 4:
            cout<<"请输入需要在第几个数前插入:";
            cin>>tmp;
            cout<<"请输入需要插入的数据";
            cin>>e.no>>e.name>>e.price;
            if(ListInsert(L,tmp,e)==OK)
                cout<<"4.Success!"<<endl;
            else
                cout<<"4.Error!"<<endl;
            break;
        case 5:
            cout<<"请输入需要查找的IBSN码:";
            cin>>e.no;
            str=LocateElemOfIBSN(L,e);
            if(str!=NULL){
                cout<<"5.Success!"<<endl;
                cout<<"\tIBNS\t\t书名\t\t价格"<<endl;
                cout<<"-----------------------------------------------"<<endl;
                cout<<"\t"<<str->data.no<<"\t"<<str->data.name<<"\t\t"<<str->data.price<<endl;
            }
            else
                cout<<"5.Error!"<<endl;
            break;
        case 6:
            cout<<"请输入需要查找的书名:";
            cin>>e.name;
            str=LocateElemOfname(L,e);
            if(str!=NULL){
                cout<<"6.Success!"<<endl;
                cout<<"\tIBNS\t\t书名\t\t价格"<<endl;
                cout<<"-----------------------------------------------"<<endl;
                cout<<"\t"<<str->data.no<<"\t"<<str->data.name<<"\t\t"<<str->data.price<<endl;
            }
            else
                cout<<"6.Error!"<<endl;
            break;
        case 7:
            cout<<"请输入需要查询第几个数据:";
            cin>>tmp;
            if(GetElem(L,tmp,e)==OK){
                cout<<"7.Success!"<<endl;
                cout<<"\tIBNS\t\t书名\t\t价格"<<endl;
                cout<<"-----------------------------------------------"<<endl;
                cout<<"\t"<<e.no<<"\t"<<e.name<<"\t\t"<<e.price<<endl;
            }
            else
                cout<<"7.Error!"<<endl;
            break;
        case 8:
            cout<<"\tIBNS\t\t书名\t\t价格"<<endl;
            cout<<"-----------------------------------------------"<<endl;
            for(int i=1;GetElem(L,i,e);++i){
                cout<<"\t"<<e.no<<"\t"<<e.name<<"\t\t"<<e.price<<endl;
            }
            break;
        case 9:
            cout<<"请输入你要删除第几个结点:";
            cin>>tmp;
            if(ListDelete(L,tmp)==OK)
                cout<<"9.Success!"<<endl;
            else
                cout<<"9.Error!"<<endl;
            break;
        case 10:
            DeleteList(L);
            cout<<"10.Delete success!"<<endl;
            break;
        case 0:
            exit(0);
            break;
        default:
            cout<<"ERROR Input!"<<endl;
            break;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/JEYMING/article/details/80054503