1.双向链表的操作
- 双向链表的基本操作包括:判断链表是否为空、计算链表的长度、遍历链表,这3中操作的方法和单链表一样,主要和双向链表中的指向后继的指针有关。
- 双向链表的插入和删除操作和单链表是有区别的:双向链表的插入和删除操作要修改指向前驱和指向后继的指针。
2.双向链表的删除:删除指定位置 i 的元素
- 1.判断输入的删除的位置是否合法,1<=i<=表长
- 2.顺着指向后继的指针域移动指针,找到第i-1个结点
- 3.令指针q指向第i个结点,
- 4.修改指针
//双向链表的删除
int ListDelete(DuLinkList &L, int i, int &e)
{
//删除链表第i个位置上的元素,并用e返回其值,1<=i<=表长
DuLNode *p;
p = L;
int j = 0;
while (p->next&&j < i - 1)
{ //找到第i-1个结点
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{
return 0;
}
DuLNode *q;
//q = new DuLNode;
q = p->next; //用q保存要删除的元素,以便释放
e = q->data;
p->next = q->next;//修改指针
q->next->prior = p;
delete q;
return 1;
}
3.双向链表的插入
- 算法思想和单链表的思想相同,只是修改的指针不同。
//双向链表的插入
int ListInsert(DuLinkList &L, int i, int e)
{
//在双向链表的第i个位置之前插入元素e,1<=i<=表长+1
struct DuLNode *p;
p = L;
int j = 0;
while (p->next&&j < i - 1)
{
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{
return 0;
}
DuLNode *s;//生成要插入的结点
s = new DuLNode;
s->data = e;
p->next->prior = s;
s->next = p->next;
p->next = s;
s->prior = p;
return 1;
}
4.双向链表的创建
- 双向链表的创建同样像单链表一样可以有两种方法:头插法和尾插法。
- 使用尾插法创建双向链表:
- 算法思想:
- 先定义一个指针p指向头结点
- 1.新结点s的前驱指向头结点L;
- 2.新结点的next指针域置空;
- 3.头结点的next指向p;
- 4.q指向p.
//尾差法创建单链表
void CreateList_L(DuLinkList &L, int n)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
DuLNode *p;
p = L;
printf("请输入链表的元素:\n");
for (int i = 0; i < n; i++)
{
printf("请输入第%d个要元素的值:", i + 1);
DuLNode *s;
s = new DuLNode;
scanf("%d", &s->data);
s->prior = p;
s->next = NULL;
p->next = s;
p = s;
}
}
- 头插法创建双向链表
//前插法创建单链表
void CreateList(LinkList &L, int n)
{
//建立带头结点的单链表L,输入n个元素的值
L = new LNode; // 先建立一个带头结点的空的单链表
L->next = NULL;
printf("输入n个元素的值:\n");
for (int i = 0; i < n; i++)
{
LNode *p;
p = new LNode; // 生成新结点
printf("请输入第%d个元素的值:", i + 1);
scanf("%d", &p->data);
// 插入
p->next = L->next;
L->next = p;
}
}
5.代码实现
- main.cpp
#include<iostream>
using namespace std;
//定义双向链表
typedef struct DuLNode
{
int data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList;
// 初始化
int InitList(DuLinkList &L)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
return 1;
}
//判断链表是否为空
int ListEmpty(DuLinkList L)
{
if (L->next == NULL)
{
return 1; //空
}
else
{
return 0; //非空
}
}
//计算链表的长度
int ListLength(DuLinkList L)
{
int length = 0;
DuLNode *p;
p = L->next;
while (p)
{
p = p->next;
length++;
}
return length;
}
//遍历链表
void TraveList(DuLinkList L)
{
DuLNode *p;
p = L->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
//头插法创建单链表
void CreateList_F(DuLinkList &L, int n)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
printf("请输入链表的元素:\n");
for (int i = 0; i < n; i++)
{
printf("请输入第%d个元素的值:", i + 1);
DuLNode *s;
s = new DuLNode;
scanf("%d", &s->data);
s->next = L->next;
s->prior = L;
L->next = s;
}
}
//尾差法创建单链表
void CreateList_L(DuLinkList &L, int n)
{
L = new DuLNode;
L->next = NULL;
L->prior = NULL;
DuLNode *p;
p = L;
printf("请输入链表的元素:\n");
for (int i = 0; i < n; i++)
{
printf("请输入第%d个要元素的值:", i + 1);
DuLNode *s;
s = new DuLNode;
scanf("%d", &s->data);
s->prior = p;
s->next = NULL;
p->next = s;
p = s;
}
}
//双向链表的删除
int ListDelete(DuLinkList &L, int i, int &e)
{
//删除链表第i个位置上的元素,并用e返回其值,1<=i<=表长
DuLNode *p;
p = L;
int j = 0;
while (p->next&&j < i - 1)
{ //找到第i-1个结点
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{
return 0;
}
DuLNode *q;
//q = new DuLNode;
q = p->next; //用q保存要删除的元素,以便释放
e = q->data;
p->next = q->next;//修改指针
q->next->prior = p;
delete q;
return 1;
}
//双向链表的插入
int ListInsert(DuLinkList &L, int i, int e)
{
//在双向链表的第i个位置之前插入元素e,1<=i<=表长+1
struct DuLNode *p;
p = L;
int j = 0;
while (p->next&&j < i - 1)
{
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)
{
return 0;
}
DuLNode *s;//生成要插入的结点
s = new DuLNode;
s->data = e;
p->next->prior = s;
s->next = p->next;
p->next = s;
s->prior = p;
return 1;
}
int main()
{
DuLinkList L;
if (InitList(L))
{
printf("链表初始化成功!\n");
}
else
{
printf("链表初始化失败!\n");
}
if (ListEmpty(L))
{
printf("链表为空!\n");
}
else
{
printf("链表非空!\n");
}
printf("请输入链表的长度:");
int n;
scanf("%d", &n);
CreateList_L(L,n);
//CreateList_F(L, n);
printf("遍历链表:\n");
TraveList(L);
printf("请输入要删除元素的位置:");
int location1;
scanf("%d", &location1);
int e;
if (ListDelete(L, location1, e))
{
printf("删除成功!\n");
}
else
{
printf("删除失败!\n");
}
printf("要删除的元素的值是:%d\n", e);
printf("删除后链表结构:\n");
TraveList(L);
printf("删除后链表长度是:%d\n", ListLength(L));
printf("请输入要插入的位置和元素的值:\n");
int location2, value;
scanf("%d,%d", &location2, &value);
if (ListInsert(L, location2, value))
{
printf("插入成功!\n");
}
else
{
printf("插入失败!\n");
}
printf("插入后的链表:\n");
TraveList(L);
printf("插入后链表的长度是:%d\n", ListLength(L));
system("pause");
return 0;
}
- 运行结果