数据结构篇——双向循环链表

双向循环链表

单链表只能向一个方向进行,也就是说元素可以直接找到后继,但不能直接找到前驱。 双向链表可以允许一个元素直接找到其后继,也可以直接找到其前驱

区别就在于:单链表中只存储了下一个元素的地址,双向链表在此基础之上增加了上一个元素的地址。

#include<stdio.h>
#include<stdlib.h>


typedef int ElemType;

typedef struct Node{
	ElemType data;
	struct Node *prior; //前驱的指针域
	struct Node *next; //后继的指针域
}Node,DoubleCirLinkList; //双向循环链表
Node *R;
void init(DoubleCirLinkList *L){
    L->data=0;
    L->next=L;
    L->prior=L;
    for(int i=1;i<=10;i++){
    	Node *n=malloc(sizeof(Node));
    	n->data=i;
    	n->next=R->next;
    	R->next=n;
    	R=n;
    	L->prior=R;
    	L->data++;
    }
}
void show(DoubleCirLinkList *L){
	Node *p=L;
	printf("[");
	while(1){
		p=p->next;
		if(p=R){
			printf("%d]\n",p->data);
			break;
		}else{
			print("%d,",p->data);
		}
	}
}
void insert(DoubleCirLinkList *L,int position,ElemType e){
	if(position<1||position>L->data+1){
		printf(">>>插入位置不合法!\n");
		return;
	}
	Node *p=L;
	// 没数据插第一个 有数据最后一个
	if(position==1&&L->data==0){
        Node *n=malloc(sizeof(Node));
    	n->data=e;
    	n->next=R->next;
    	R->next=n;
    	R=n;
    	L->prior=R;
    	L->data++;
	}else{
		Node *p=L;
		for(int i=1;i<position;i++){
			p=p->next;
		}
		Node *n=malloc(sizeof(Node));
		n->data=e;
		p->next->prior=n;
		n->next=p->next;
		p->next=n;
		n->data++;
	}
	for(int i-1;i<position;i++){
		p=p->next;
	}


}
void delete(DoubleCirLinkList *L,int position,ElemType *e){
	if(L->data==0){
		printf("空表!\n");
		return;
	}
	if(position<1||position>L->data){
        printf(">>>删除位置不合法!\n");
	}
	if(position==1&&L->data==1){ // 只有一个·元素

	}else if(position==L->data&&L->data>1){
		Node *n=L->next;
		*e=n->data;
		free(n);
		L->data--;
		L->next=L;
		L->prior=L;
		R=L; // 重置R指针
	}else if(position==L->data&&L->data>1){ // 删尾
		Node *n=R;
		R->prior->next=R->next;
		R->next->prior=R->prior;
		R=R->prior;
		*e=n->data;
		free(n);
		L->data--;
	}else{
		Node *p=L;
		for(int i=1;i<position;i++){
			p=p->next;
		}
		Node *n=p->next;
		n->next->prior=p;
		p->next=n->next;
		L->data--;
		*e=n->data;
		free(n);
    }
}
void main(){
	DoubleCirLinkList L;
	int choice;
	ElemType e;
	printf("------------双向循环链表---------\n");
	printf("1.初始化\n");
    printf("2.插入\n");
    printf("3.删除\n");
    printf("4.打印\n");
    printf("0.退出\n");
    while(1){
    	printf(">>>请选择:");
    	scanf("%d",&choice);
    	switch(choice){
    		case 1:
    		    init(&L);
    		    break;
    		case 2:
                printf(">>>请输入插入的位置:");
                scanf("%d",&position);
                printf(">>>请输入插入的元素:");
                scanf("%d",e);
                insert(&L,position);
    		    break;
    		case 3:
                printf(">>>请输入删除的位置:");
                scanf("%d",&position);
                delete(&L,position,&e);
                printf(">>>删除元素%d\n",e);
    		    break;
    		case 4:
    		    show(&L);
    		    break;
    		case 0:
    		    return;
    	}
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值