C++数据结构之单链表(henu.hjy)

注重于程序健壮性的单链表,在学习单链表是我的方法是画图,当你理解所学,在写代码时画图是帮你梳理思路的一个很好方法

一下是我的代码,仅供参考,我写的有配套的实验报告——对于代码的解释以及一些我在学习中出现的问题,如有需要评论区留下邮箱(可能不会及时回复,望谅解)

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

#define TRUE 1;
#define FALSE 0;
#define ERROR -1;
#define LEN sizeof(Lnode)

using namespace std;

typedef struct Lnode
{
    int data;
    struct Lnode *next;
}Lnode,*Linklist;

typedef int Status;
typedef int Elemtype;

void title();
Status InitList(Linklist *L);   //创建链表
Status DestroyList(Linklist *L); //销毁链表
Status ListLength(Linklist L);  //链表长度
Status GetElement(Linklist L,int i,Elemtype *e);//返回指定位置的元素值
Status LocateElem(Linklist L,int *e);//通过位序返回元素值
Status PiorElem(Linklist L,int e);//通过元素来查找前驱
Status NextElem(Linklist L,int e);//通过元素来查找后继
Status ListInsert(Linklist *L,int i,int e);//通过位置插入元素
Status ListDelete(Linklist *L,int i);//删除元素
Status ListTraverse(Linklist L);//遍历输出
Status CreatList(Linklist *L,int n);//输入n个数字


int main()
{
    Linklist L;
    L=NULL;
    title();
    //输入选项
    int option;
    cin>>option;
    int ads = 0;
    while(option!=0)
    {
        ads = 0;
        switch(option)
        {
            case 1:
                ads=InitList(&L);
                break;
            case 2:
                ads=DestroyList(&L);
                if(ads){cout<<"成功销毁单链表"<<endl;}
                break;
            case 3:
                ads=ListLength(L);
                if(ads!=-1){cout<<"单链表长度为"<<ads<<endl;}
                break;
            case 4:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int loc,e;
                e=0;
                cout<<"请输入元素位置:";
                cin>>loc;
                ads=GetElement(L,loc,&e);
                if(ads==1)
                {
                    cout<<"在位置"<<loc<<"元素值为"<<e<<endl;
                }
                break;
            case 5:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int n;
                cout<<"请输入想找的元素";
                cin>>n;
                ads=LocateElem(L,&n);
                break;
            case 6:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int num;
                cout<<"请输入一个元素:"<<endl;
                cin>>num;
                ads = PiorElem(L,num);
                break;
            case 7:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int num1;
                cout<<"请输入一个元素:"<<endl;
                cin>>num1;
                ads = NextElem(L,num1);
                break;
            case 8:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int num2;
                ads = ListLength(L);
                cout<<"请输入元素插入的位置:"<<endl;
                cin>>num2;
                if(num2<1||num2>(ads+1)){
                    cout<<"请输入元素位置在1-"<<ads+1<<"之间"<<endl;
                    break;
                }
                int number;
                cout<<"请输入元素的值:"<<endl;
                cin>>number;
                ads = ListInsert(&L,num2,number);
                break;
            case 9:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int num3;
                ads = ListLength(L);
                cout<<"请输入元素删除的位置:"<<endl;
                cin>>num3;
                if(num3<1||num3>ads){
                    cout<<"请输入元素位置在1-"<<ads<<"之间"<<endl;
                    break;
                }
                ads = ListDelete(&L,num3);
                break;
            case 10:
                ads = ListLength(L);
                if(ads == 0){
                    cout<<"这是一个空表!"<<endl;
                    break;
                }
                else if(ads>0){
                    cout<<"单链表中的元素为:"<<endl;
                    ListTraverse(L);
                    cout<<endl;
                    break;
                }
                break;
            case 11:
                if(L==NULL){
                    cout<<"单链表不存在!"<<endl;
                    break;
                }
                int num4;
                cout<<"请输入插入的元素个数:"<<endl;
                cin>>num4;
                if(num4<1){
                    cout<<"输入插入元素的数目有误!"<<endl;
                    break;
                }
                ads = CreatList(&L,num4);
                break;
            default:
                cout<<"输入操作有误,请重新输入:"<<endl;
        }
        cout<<"输入选项:"<<endl;
        cin>>option;
    }
    return 0;
}

Status InitList(Linklist *L)//二级指针,我对它的理解:malloc函数返回的是一个区域的首地址,而我们的目的就是开辟区域的首地址等于链表的首地址,因而以二级指针传入
{
    if(*L!=NULL)
    {
        cout<<"以存在单链表,请销毁后再初始化!"<<endl;
        return ERROR;
    }
    Linklist p;
    p = (Linklist)malloc(LEN);
    if(p==NULL)
    {
        cout<<"申请内存空间失败"<<endl;
        return FALSE;
    }
    p->next=NULL;
    *L = p;
    cout<<"初始化成功!"<<endl;
    return TRUE;
}

Status DestroyList(Linklist *L)      //传单链表的首地址
{
    Linklist p;
    if(*L!=NULL)
    {
        while(*L)
        {
            p=*L;
            *L=(*L)->next;
            free(p);
        }
        return TRUE;
    }
    else
    {
        cout<<"链表不存在"<<endl;
        return FALSE;
    }
}

Status ListLength(Linklist L)
{
    Linklist p;
    if(L==NULL){
        cout<<"单链表不存在"<<endl;
        return ERROR;
    }
    p=L;
    int i=0;
    for(i=0;p->next!=NULL;i++)
    {
        p=p->next;
    }
    return i;
}

Status GetElement(Linklist L,int i,Elemtype *e)
{
    Linklist p;
    p = L->next;
    int j=1;
    while(p&&j<i)
    {
        p=p->next;
        j++;
    }
    if(!p||j>i)
    {
        cout<<"请输入正确的位置"<<endl;
        return FALSE;
    }else
    {
        *e=p->data;
    }
    return TRUE;
}

Status LocateElem(Linklist L,int *e)
{
    Linklist p;
    int result;
    result = ListLength(L);
    if(result==0){
        cout<<"这是一个空表"<<endl;
        return FALSE;
    }
    else if(result==-1){
        return FALSE;
    }
    int loc[100]={0};//在链表中可能会有许多相同的值,以数组形式进行输出
    int j=0;
    p=L->next;
    for(int i=1;p!=NULL;i++)
    {
        if(p->data==*e)
        {
            loc[j]=i;
            j++;
        }
        p=p->next;
    }
    if(loc[0]==0)
    {
        cout<<"不存在这样元素"<<endl;
        return TRUE;
    }else
    {
        cout<<"位次是";
        for(int i=0;loc[i+1]!=0;i++)
        {
            cout<<loc[i]<<endl;
        }
        cout<<endl;
        return TRUE;
    }
}

Status PiorElem(Linklist L,int e)
{
    int i = 0;
    Linklist p,q;
    p = L->next;
    while(p!=NULL){
        if(p->data==e&&i==0){
            cout<<"首个元素,没有直接前驱"<<endl;
            break;
        }
        if(p->data==e&&i!=0){
            cout<<"单链表中的元素前驱为:"<<(q->data)<<endl;
            break;
        }
        q = p;
        p = p->next;
        i++;
    }
    if(p==NULL){
        cout<<"该单链表中没有元素!"<<endl;
        return FALSE;
    }
    return TRUE;
}

Status NextElem(Linklist L,int e)
{
    Linklist p;
    p = L->next;
    while(p!=NULL){
        if(p->data==e){
            if(p->next==NULL){
                cout<<"该元素没有直接后继"<<endl;
                break;
            }
            if(p->next!=NULL){
                cout<<"单链表中的元素后继为:"<<(p->next->data)<<endl;
                break;
            }
        }
        p = p->next;
    }
    return TRUE;
}

Status ListInsert(Linklist *L,int i,int e)
{
    if(*L==NULL){
        cout<<"单链表不存在!"<<endl;
        return FALSE;
    }
    int j=1;
    Linklist p,s;
    s = (Linklist)malloc(LEN);
    if(s==NULL){
        cout<<"申请内存空间失败!"<<endl;
        return ERROR;
    }
    s->data = e;
    p = (*L);
    while(j<i&&p!=NULL){
        p=p->next;
        j++;
    }
    s->next = p->next;
    p->next = s;
    cout<<"插入成功!"<<endl;
    return TRUE;
}

Status ListDelete(Linklist *L,int i)
{
    if(*L==NULL){
        cout<<"单链表不存在!"<<endl;
        return FALSE;
    }
    Linklist p,q;
    p = (*L);
    int j=0;
    while(p!=NULL&&j<i){
        q = p;
        p = p->next;
        j++;
    }
    q->next=p->next;
    cout<<"删除的元素是"<<p->data<<endl;
    free(p);
    cout<<"删除成功"<<endl;
    return TRUE;
}

Status ListTraverse(Linklist L)
{
    Linklist p;
    p = L->next;
    while(p!=NULL){
        cout<<p->data<<"    ";
        p = p->next;
    }
    return TRUE;
}

Status CreatList(Linklist *L,int n)//n 为想要插入元素的个数  头插法
{
    if(*L==NULL){
        cout<<"单链表不存在!"<<endl;
        return FALSE;
    }
    Linklist p;
    int newnum[n];
    newnum[n] = {0};
    int a = 0;
    int j = 0;
    cout<<"请输入插入的n个元素:"<<endl;
    for(j=0;j<n;j++)
    {
        cin>>a;
        newnum[j]=a;
    }
    if(j!=n){
        cout<<"输入个数小于"<<n<<"个"<<endl;
        return FALSE;
    }
    for(int i=1;i<=n;i++)
    {
        p = (Linklist)malloc(LEN);
        if(!p){
            cout<<"申请空间失败!"<<endl;
            return ERROR;
        }
        p->data = newnum[i-1];
        p->next = (*L)->next;
        (*L)->next = p;
    }
    cout<<"插入成功!"<<endl;
    return TRUE;
}


void title()
{
    cout<<"*******************************************"<<endl;
    cout<<"******* 1.初始化或重置链表         ********"<<endl;
    cout<<"******* 2.销毁链表                 ********"<<endl;
    cout<<"******* 3.链表中数据元素的个数     ********"<<endl;
    cout<<"******* 4.所指位序的元素值         ********"<<endl;
    cout<<"******* 5.链表已存在元素的位序     ********"<<endl;
    cout<<"******* 6.请输入元素,求直接前驱   ********"<<endl;
    cout<<"******* 7.请输入元素,求直接后继   ********"<<endl;
    cout<<"******* 8.在第i个位置插入元素      ********"<<endl;
    cout<<"******* 9.删除第i个元素            ********"<<endl;
    cout<<"******* 10.输出所输入的链表元素    ********"<<endl;
    cout<<"******* 11.输入链表元素            ********"<<endl;
    cout<<"******* 0.退出                     ********"<<endl;
    cout<<"*******************************************"<<endl;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值