数据结构(C语言版)代码详解03-双链表

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

/***双链表:
与单链表的区别是: 结构体多一个 结构体指针pre指向上一个结点的地址 
***/

typedef struct Node{
	int data;
	struct Node* next;
	struct Node* pre;
}Node; 

/***初始化:
1、创建头节点,开辟空间,初始化结构体内容,返回头节点的地址 
***/
Node* InitList(){
	Node* L=(Node*)malloc(sizeof(Node));
	L->data=0;
	L->next=NULL;
	L->pre=NULL;
	return L;
}

/***增加结点:头插法
作用:在头部(头节点后)插入新结点,并将数据赋值给新结点
实现:要处理的有三块,新结点,前趋结点(头节点L),后继结点(头节点L->next)。
1、前趋结点的next指向新结点的地址
2、后继结点的pre指向新结点的地址
3、新结点的pre变成前趋结点
4、新结点的next变成后趋结点
要注意的是:如果链表只有头节点的时候,只需要改变头节点的next和新结点pre、next 
***/
void headInsert(Node* L,int data){
	Node* node=(Node*)malloc(sizeof(Node));
	node->data=data;
	node->next=L->next;
	node->pre=L;
	L->data++;
	if(L->next==NULL){//只有头结点的情况 
		L->next=node;
	}
	else{
		L -> next -> pre = node;
		L->next=node;
	}
}

/***增加结点:尾插法
作用:在末尾插入新结点
实现:新结点的pre等于前趋结点,前趋结点的next等于新结点,新结点的next等于前趋结点的next 
***/
void tailInsert(Node* L,int data){
	Node* node=(Node*)malloc(sizeof(Node));
	node->data=data;
	L->data++;
	Node* p=L;
	while(p->next){
		p=p->next;
	}
	node->next=p->next;
	node->pre=p;
	p->next=node;
}

/***删除结点:
作用:删除目的结点
实现:要操作前趋结点,目标结点,后继结点。
1、前趋结点的next变成目标结点的next
2、后继结点的pre变成目标结点的pre(前提是有后继结点)
3、释放目的结点 
***/
int deleteList(Node* L,int data){
	Node* p=L->next;
	while(p){
		if(p->data==data){
			p->pre->next=p->next;
			if(p->next){
				p->next->pre=p->pre;
			}
			L->data--;
			free(p);
			return 1;
		}
		p=p->next;
	}
	return 0;
}

/***遍历双链表 
***/
void printList(Node* L){
	Node* p=L->next;
	while(p){
		printf("%d->",p->data);
		p=p->next;
	}
	printf("NULL\n");
}

int main(){
	Node* L=InitList();  //得到头结点的地址 
	headInsert(L,5);
	headInsert(L,4);
	headInsert(L,3);
	headInsert(L,2);
	headInsert(L,1);
	tailInsert(L,6);
	tailInsert(L,7);
	tailInsert(L,8);
	tailInsert(L,9);
	tailInsert(L,10);
	
	printList(L);
	
	deleteList(L,5);
	deleteList(L,10);
	deleteList(L,1);
	
	printList(L);
	return 0;
}

这里要注意的:

1、头插法中,链表有多个结点和只有头结点的差别在于 后继结点(L->next)的pre。如果一开始就将头节点的next赋值为新结点,则获取不到新结点的后继结点(即L->next)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值