此代码含自定义包
双向链表即,节点有前驱节点,后继节点,结构如下
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<<"结束命令";
}
测试结果如下