双向链表的操作
双向链表的基本操作包括:判断链表是否为空、计算链表的长度、遍历链表,这3中操作的方法和单链表一样,主要和双向链表中的指向后继的指针有关。
双向链表的插入和删除操作和单链表是有区别的:双向链表的插入和删除操作要修改指向前驱和指向后继的指针。
双向链表的删除:删除指定位置 i 的元素
1.判断输入的删除的位置是否合法,1<=i<=表长
2.顺着指向后继的指针域移动指针,找到第i-1个结点
3.令指针q指向第i个结点,
4.修改指针
//双向链表的删除
int ListDelete(DuLinkList &L,int i,int &e){
//删除链表第i个位置上的元素,并用e返回其值
// 1<=i<=表长
struct DuLNode *p;
p=L;
//struct DuLNode *q;
int j=0;
while(p->next&&j<i-1){//找到第i-1个结点
++j;
p=p->next;
}
if(!(p->next)||j>i-1){
return 0;
}
struct 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){
++j;
p=p->next;
}
if(!(p->next)||j>i-1){
return 0;
}
struct DuLNode *s;//生成要插入的结点
s=new DuLNode;
s->data=e;
p->next->prior=s;
s->next=p->next;
p->next=s;
s->prior=p;
return 1;
}
具体实现:
#include<stdio.h>
#include<iostream>
using namespace std;
#define MAX 100
//定义双向链表
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;
struct DuLNode *p;
p=L->next;
while(p){
p=p->next;
++length;
}
return length;
}
//遍历链表
void TraveList(DuLinkList L){
struct 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=n;i>0;--i){
printf("请输入第%d个元素的值:",i);
struct DuLNode *s;
s=new DuLNode;
s->next=NULL;
s->prior=NULL;
scanf("%d",&s->data);
s->next=L->next;
if(L->next!=NULL)
L->next->prior=s;
s->prior=L;
L->next=s;
}
}
//尾差法创建单链表
void CreateList_L(DuLinkList &L,int n){
L=new DuLNode;
L->next=NULL;
L->prior=NULL;
struct DuLNode *p;
p=L;
printf("请输入链表的元素:\n");
for(int i=0;i<n;i++){
printf("请输入第%d个要元素的值:",i+1);
struct DuLNode *s;
s=new DuLNode;
//每个新结点的前驱和后继初始时都指向空
s->next=NULL;
s->prior=NULL;
scanf("%d",&s->data);
p->next=s;
s->prior=p;
p=s;
}
}
//双向链表的删除
int ListDelete(DuLinkList &L,int i,int &e){
//删除链表第i个位置上的元素,并用e返回其值
// 1<=i<=表长
struct DuLNode *p;
p=L;
//struct DuLNode *q;
int j=0;
while(p->next&&j<i-1){//找到第i-1个结点
++j;
p=p->next;
}
if(!(p->next)||j>i-1){
return 0;
}
struct 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){
++j;
p=p->next;
}
if(!(p->next)||j>i-1){
return 0;
}
struct 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));
}