双向链表的操作
双向链表的基本操作包括:判断链表是否为空、计算链表的长度、遍历链表,这3中操作的方法和单链表一样,主要和双向链表中的指向后继的指针有关。
双向链表的插入和删除操作和单链表是有区别的:双向链表的插入和删除操作要修改指向前驱和指向后继的指针。
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 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;
- 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;
- scanf("%d",&s->data);
- p->next=s;
- s->prior=p;
- p=s;
- }
- }
- //双向链表的删除
- int ListDelete(DuLinkList &L,并用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 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));
- }