数据结构学习之双链表基本操作
数据结构学习之双链表基本操作
0x1 前言
今天实验课,学习了下双链表的写法,这里记录下。
0x2 正文
题目要求如下:
本实验的双链链表元素的类型为char,完成如下实验要求:
(1)初始化单链表h
(2)采用尾插法依次插入a、b、c、d、e
(3)输出单链表h
(4)输出单链表h的长度
(5)判断单链表h是否为空
(6)输出单链表h的第3个元素
(7)输出元素a的逻辑位置
(8)在第4个元素位置上插入元素f
(9)输出单链表h
(10)删除单链表h的第3个元素
(11)输出单链表h
(12)释放单链表h
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef char Elemtype;
typedef struct DNode
{
Elemtype data; //存放元素值
struct DNode * prior; //指向前驱结点
struct DNode * next; //指向后继结点
}DLinkNode;
// 初始化双链表
void InitList(DLinkNode *&h)
{
h=(DLinkNode *)malloc(sizeof(DLinkNode));
h->prior=h->next=NULL; //前后指针域置为空
}
// 尾插法插入
void InsertListR(DLinkNode *&h,Elemtype a[],int n)
{
DLinkNode *s,*r;
r=h;
for(int i=0;i<n;i++)
{
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=a[i];
r->next=s;
s->prior=r;
r=s;
}
r->next=NULL;
}
//输出双链表
void DispList(DLinkNode *h)
{
DLinkNode *p;
p=h->next;
while(p!=NULL)
{
printf("%c ",p->data);
p=p->next;
}
printf("\n");
}
//输出双链表h的长度
int ListLength(DLinkNode *h)
{
int n=0;
DLinkNode *p=h->next;
while(p!=NULL)
{
n++;
p=p->next;
}
return(n);
}
//判断线性表是否为空表
bool ListEmpty(DLinkNode *h)
{
return(h->next==NULL);
}
//输出指定下标的元素
char LocateElemByIndex(DLinkNode *h,int i)
{
DLinkNode *p=h;
while(p->next!=NULL&&i)
{
i--;
p=p->next;
}
if(p->next==NULL)
{
return(false);
}
else
return(p->data);
}
// 输出指定元素的位置
int LocateElem(DLinkNode *h,Elemtype e)
{
int n=1;
DLinkNode *p=h->next;
while(p!=NULL&&p->data!=e)
{
n++;
p=p->next;
}
if(p==NULL)
{
return(0);
}else
return(n);
}
//在指定位置插入指定的元素
bool ListInsert(DLinkNode *&h,int i,Elemtype e)
{
DLinkNode *p=h,*s;
int j=0;
if(i<=0) return(false);
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
{
return false;
}
s=(DLinkNode *)malloc(sizeof(DLinkNode));
s->data=e;
s->prior=p;
s->next=p->next;
if(p->next!=NULL)
p->next->prior=s;
p->next=s;
return(true);
}
//删除指定下标元素
bool ListDelete(DLinkNode *&h,int i,Elemtype &e)
{
DLinkNode *p=h,*q;
int j=0;
if(i<=0) return(false);
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
{
return(false);
}else
{
q=p->next;
if(q==NULL)
return(false);
e=q->data;
p->next=q->next;
if(p->next!=NULL)
q->prior=p;
free(q);
return(true);
}
}
//释放循环链表
void DestroyList(DLinkNode *&h)
{
DLinkNode *pre=h,*p=h->next;
while(p!=NULL)
{
free(pre);
pre=p;
p=p->next;
}
free(pre);
cout<< "List has been destroyed!" <<endl;
}
int main()
{
DLinkNode *h;
char e;
InitList(h);
char a[5]={'a','b','c','d','e'};
InsertListR(h,a,5);
DispList(h);
cout<< ListLength(h) <<endl;
if(ListEmpty(h))
{
cout<< "List is Empty!"<<endl;
}else
{
cout<<"List isn't Empty!"<<endl;
};
cout<< LocateElemByIndex(h,3)<<endl;
cout<< LocateElem(h,'a')<<endl;
ListInsert(h,4,'f');
DispList(h);
ListDelete(h,3,e);
DispList(h);
DestroyList(h);
return 0;
}
运行结果如下图:
0x3 总结
感觉和单链表不是很大区别,主要是在插入或者删除的时候注意处理下前继指针,比如判断后继是否存在,然后修改后继的前继指针。
相关文章