双向链表基本操作(代码实现)

此代码含自定义包
双向链表即,节点有前驱节点,后继节点,结构如下

typedef struct DNode{
    DataType Data;
    struct DNode* pre;
    struct DNode* next;
}DNode,*DLinkList;

双向链表基本操作如下(及下包中所含)
程序头文件(head.h)

#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
#include <bits/stdc++.h>

typedef int DataType;
typedef struct DNode{
    DataType Data;
    struct DNode* pre;
    struct DNode* next;
}DNode,*DLinkList;

void InitList(DLinkList* Phead,DLinkList* Ptail);//建立双向链表的头,尾节点.
bool DList_Empty(DLinkList Phead);//判断双向链表是否为空
void CreatFrom_Head(DLinkList Phead);//头插法给双向链表加入成员
void CreatFrom_Fail(DLinkList Pfail);//尾插法给双向链表加入成员
void DList_Insert(DLinkList Phead,DLinkList Ptail,int locate,DataType data);//在位于locate的成员后插入data
int DList_length(DLinkList Phead,DLinkList Ptail);//求链表长度
DNode* Get(DLinkList Phead,DLinkList Ptail,int n);//查找第n个成员
int Locate(DLinkList Phead,DLinkList Ptail,int data);//查找成员的位置
void DList_Del(DLinkList Phead,DLinkList Ptail,DataType data);//删除在成员data
void DList_Print(DLinkList Phead,DLinkList Ptail);//遍历双向链表
void DList_Dstory(DLinkList Phead);//销毁链表

#endif // HEAD_H_INCLUDED

对操作的实现
程序文件(head.cpp)

#include <bits/stdc++.h>
using namespace std;

typedef int DataType;//成员类型

typedef struct DNode{
    DataType Data;
    struct DNode* pre;//指向前驱节点
    struct DNode* next;//指向后继节点
}DNode,*DLinkList;

void InitList(DLinkList* Phead,DLinkList* Ptail)//双向节点初始化
{
    //Phead是三级指针,指向结构体的是二级指针,所以程序中要*Phead。
    *Phead = (DLinkList)malloc(sizeof(DNode));
    *Ptail = (DLinkList)malloc(sizeof(DNode));
    if((*Phead)==NULL||(*Ptail)==NULL)
            cout<<"双向链表建立失败"<<endl;
    else
    {
        (*Phead)->pre = (*Phead)->next = NULL;
        (*Ptail)->pre = (*Ptail)->next = NULL;
        (*Phead)->next = (*Ptail);
        (*Ptail)->pre = (*Phead);
    }
}

bool DList_Empty(DLinkList Phead)//判断双向链表是否为空
{
    if(Phead->next->next == NULL)
        return false;
    else
        return true;

}

void CreatFrom_Head(DLinkList Phead)//头插法插入成员
{
    int data;
    DNode* p;
    while((cin>>data)!=0&&data!=-1)
    {
        getchar();
        p = (DLinkList)malloc(sizeof(DNode));
        p->Data = data;
        //指针交换核心代码。
        p->next = Phead->next;
        Phead->next->pre = p;
        Phead->next = p;
        p->pre = Phead;
    }
}

void CreatFrom_Fail(DLinkList Pfail)//尾插法插入成员
{
    int data;
    DNode* p;
    while((cin>>data)!=0&&data!=-1)
    {
        getchar();
        p = (DLinkList)malloc(sizeof(DNode));
        p->Data = data;
        //指针交换核心代码
        p->pre = Pfail->pre;
        Pfail->pre->next = p;
        Pfail->pre = p;
        p->next = Pfail;
    }
}

int DList_length(DLinkList Phead,DLinkList Ptail)//链表长度
{
    int i=0;
    DNode* p = Phead->next;
    while(p!=Ptail)
    {
        p = p->next;
        i++;
    }
    return i;
}

DNode* Get(DLinkList Phead,DLinkList Ptail,int n)//查找第n个成员
{
    int len = DList_length(Phead,Ptail);
    if(n>0&&n<=len)
    {
         int i=1;
         DNode* p = Phead->next;
         while(i<n)
         {
             p = p->next;
             i++;
         }
         return p;
    }
    else
    {
        return NULL;
    }
}

void DList_Insert(DLinkList Phead,DLinkList Ptail,int locate,DataType data)//在locate位置插入成员
{
    DLinkList Ph = Get(Phead,Ptail,locate)->pre;//调用Get()找到成员
    DLinkList p = (DLinkList)malloc(sizeof(DNode));
    if(Ph!=NULL)
    {
        p->Data = data;
        //插入元素核心代码
        p->next = Ph->next;
        Ph->next->pre = p;
        Ph->next = p;
        p->pre = Ph;
    }
    else
        cout<<"插入位置不合法"<<endl;

}

void DList_Del(DLinkList Phead,DLinkList Ptail,DataType data)//删除成员data
{
    DLinkList p = Phead->next;
    while(p->Data!=data&&p->next!=NULL)//找到data位置
    {
        p = p->next;
    }
    if(p->Data==data)//删除该节点并且释放空间
    {
        DLinkList h = p->pre;
        DLinkList f = p->next;
        h->next = f;
        f->pre = h;
        free(p);
    }
    else
         cout<<data<<"不在该链表中"<<endl;

}

void DList_Print(DLinkList Phead,DLinkList Ptail)//遍历双向链表
{
    cout<<"双向链表的成员有(从头开始遍历): ";
    DNode* ph = Phead->next;
    DNode* pt = Ptail->pre;
    while(ph->next!=NULL)
    {
        cout<<ph->Data<<" ";
        ph = ph->next;
    }
    cout<<"\n双向链表的成员有(从尾开始遍历): ";
    while(pt->pre!=NULL)
    {
        cout<<pt->Data<<" ";
        pt = pt->pre;
    }
    cout<<endl;
}

int Locate(DLinkList Phead,DLinkList Ptail,int data)//查找成员data的位置
{
    int i=1;
    DLinkList p = Phead->next;
    while(p->Data!=data&&p->next!=NULL)
    {
        p = p->next;
        i++;
    }
    if(p->next==NULL)
    {
        cout<<data<<"没在该链表中"<<endl;
        return NULL;
    }
    else
        return i;
}

void DList_Dstory(DLinkList Phead)//销毁链表
{
    DLinkList p = Phead;
    DLinkList q;
    while(p!=NULL)
    {
        q = p;
        p = p->next;
        free(q);
    }
}

测试程序如下
程序文件(main.cpp)

#include <bits/stdc++.h>
#include "head.h"
using namespace std;
int main()
{
    int step;
    DLinkList head,tail;
    InitList(&head,&tail);//建立双向链表的头尾节点
    cout<<"*****************************"<<endl;
    cout<<"链表建立完毕,请选择指令"<<endl;
    cout<<"*****************************"<<endl;
    cout<<"-1 :结束操作\n"<<"1  :头插法插入元素\n"<<"2  :尾插法插入元素\n"<<"3  :插入操作"<<endl;
    cout<<"4  :删除操作\n"<<"5  :遍历该链表\n"<<"6  :求表长操作\n"<<"7  :按位置查找成员"<<endl;
    cout<<"8  :按值查找位置\n"<<"9  :判断链表是否为空\n"<<"0  :销毁链表"<<endl;
    cout<<"*****************************"<<endl;
    cout<<"请输指令: ";
    while((cin>>step!=0)&&step!=-1)
    {
        if(step==1)
        {
            cout<<"请输入插入的成员,空格分割,”-1“表示结束"<<endl;
            CreatFrom_Head(head);
        }
        else if(step==2)
        {
            cout<<"请输入插入的成员,空格分割,”-1“表示结束"<<endl;
            CreatFrom_Fail(tail);
        }
        else if(step==3)
        {
            int locate,data;
            cout<<"请输入插入成员"<<endl;
            cin>>data;
            cout<<"输入插入位置"<<endl;
            cin>>locate;
            DList_Insert(head,tail,locate,data);
        }
        else if(step==4)
        {
            int locate;
            cout<<"请输入需要删除成员"<<endl;
            cin>>locate;
            DList_Del(head,tail,locate);
        }
        else if(step==5)
        {
            DList_Print(head,tail);
        }
        else if(step==6)
        {
            int len = DList_length(head,tail);
            cout<<"双向链表的长度为"<<len<<endl;
        }
        else if(step==7)
        {
            int locate;
            DLinkList p;
            cout<<"请输入要找成员的位置"<<endl;
            cin>>locate;
            p = Get(head,tail,locate);
            if(p==NULL)
                cout<<"位置选取不合法"<<endl;
            else
                cout<<"该位置的成员是"<<p->Data<<endl;
        }
        else if(step==8)
        {
            int data;
            cout<<"请输入需要查找的成员值"<<endl;
            cin>>data;
            data = Locate(head,tail,data);
            cout<<"该成员的位置为:"<<data<<endl;
        }
        else if(step==9)
        {
            if(DList_Empty(head)) cout<<"双向链表不为空"<<endl;
            else cout<<"空链表"<<endl;
        }
        else if(step==0)
        {
            DList_Dstory(head);
            cout<<"链表被销毁"<<endl;
        }
        cout<<"请输指令: ";
    }
    cout<<"结束命令";
}

测试结果如下
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值