双链表的操作【和循环双链表操作】

首先你可以在计算机内部输出node ,  node->data, node->pre, node->next, 的地址,你会发现,他们都不一样但是是挨着的 所以,要先不混淆 node->next=node; 不同于 node->next=node->data;[并且后者数据类型都可能不一样]。

在比如说 node *a,*b; a是b的前一个结点、,那么b->pre->next==a->next;这在计算机内部只是地址的变换罢了【计算机也只认地址啦】

1.初始化链表

 typedef struct Node{
     int data;                            //本代码中作为计数器 
     struct Node* pre;
     struct Node* next;
 }Node;

2.插入结点

头插法:插在头结点后面

if(L->data==0【//链表为空】){        //只有头结点,该两个指针域即可
        node->next=L->next;
        node->pre=L;
        L->next=node;   
      }else{
          //多节点,4个指针要改,可以自己先试试 
         node->pre=L;
         node->next=L->next;
         L->next->pre=node;
         L->next=node;

尾插法:找到最后一个结点,赋值给node,然后

n->next=node->next;
n->pre=node;
node->next=n;

3.删除结点:记得释放该结点

node->pre->next=node->next;
node->next->pre=node->pre; 

4.遍历

定义一个局部变量循环链表即可。

/*双链表*/
 #include<stdio.h>
 #include<stdlib.h>
 typedef struct Node{
 	int data;							//本代码中作为计数器 
 	struct Node* pre;
 	struct Node* next;
 }Node;
 //初始化
 Node* initList()
 {
 	Node* L=(Node*)malloc(sizeof(Node));
 	L->data=0;
 	L->pre=NULL;
 	L->next=NULL;
 	return L;
 } 
 //头插法
 void headList(Node* L,int data)
 {
 	Node* node=(Node*)malloc(sizeof(Node));
 	node->data=data;
 	//判断链表是否为空,只有一个结点的话改变2个指针域
	  if(L->data==0){
  		//链表为空
		node->next=L->next;
		node->pre=L;
		L->next=node;   
  	}else{
	  	//多节点,4个指针要改,可以自己先试试 
	 	node->pre=L;
	 	node->next=L->next;
	 	L->next->pre=node;
	 	L->next=node;
	  }
	  L->data ++;
 } 
 //尾插法
 void tailList(Node* L,int data)
 {
 	Node* node=L;
 	Node* n=(Node*)malloc(sizeof(Node));
 	n->data=data;
 	while(node->next){
	 	node=node->next;
	 }
 	n->next=node->next;
 	n->pre=node;
 	node->next=n;
 	L->data++;
 } 
 //删除操作
 int _delete(Node* L,int data)
 {
 	Node* node=L->next;
 	while(node){
	 	if(node->data==data){
	 		//删除操作,断开有关系的4个指针 
			node->pre->next=node->next;
			node->next->pre=node->pre;  
			free(node);
			return 1; 
	 	}
	 node=node->next;	
	 }
	 return 0;
 } 
 //遍历链表
 void printList(Node* L)
 {
 	Node *node=L->next;
 	while(node){
	 	printf("%d->",node->data);
	 	node=node->next;
	 }
	 printf("NULL\n");
 } 
 int main(){
 	Node* L=initList();
 	headList(L,1);
 	headList(L,2);
 	headList(L,3);
 	headList(L,4);
 	tailList(L,5);
 	_delete(L,1);
 	_delete(L,3);
 	printList(L);
 	free(L);
 	return 0;
 }

--------------------分割线----------

它和双链表的区别仅仅在于 最后一个结点的next指向头结点 和 头结点的pre指向最后一个结点 而已【主要目的是构成一个闭环】。

/*循环双链表*/
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
	int data;
	struct Node* pre;
	struct Node* next;
}Node;
//初始化链表
Node* initNode()
{
	Node* L=(Node*)malloc(sizeof(Node));
	L->data=0;
	L->pre=L;
	L->next=L;
	return L;
}
//头插法增加结点 
void headinsert(Node* L,int data)
{
	Node* node=(Node*)malloc(sizeof(Node));
	node->data=data;
	if(L->data==0){
		//链表为空
		node->next=L;			//node->next=L->next;在初始化的时候,L->next=L; 
		node->pre=L;
		L->next=node;
		L->pre=node; 
	}else{
		node->next=L->next;
		node->pre=L;
		L->next->pre=node;
		L->next=node;
	}
	L->data+=1;
}
//尾插法增加结点
void tailNode(Node* L,int data)
{
	Node* node=L->pre;
	Node* n=(Node*)malloc(sizeof(Node));
	n->data=data;
	n->pre=node;
	n->next=L;
	L->pre=n;
	node->next=n;			//双重意义 
	L->data++;
} 
//删除结点[找到要删的]
int _delete(Node* L,int data)
{
	Node* node=L->next;
	while(node!=L){			//因为这是循环链表,最后的next指向第一个 
		if(node->data==data){
			node->pre->next=node->next;
			node->next->pre=node->pre;
			L->data--;
			free(node);
			return 1;
		}
		node=node->next;
	}
}
//遍历结点
void printNode(Node* L)
{
	Node* node=L->next;
	while(node!=L){			//循环链表的结束条件 
		printf("%d->",node->data);
		node=node->next;
	}
	printf("NULL \n");
}
 
int main(){
	Node* L=initNode();
	headinsert(L,1);
	headinsert(L,2);
	headinsert(L,4);
	headinsert(L,5);
	tailNode(L,6);
	tailNode(L,7);
	_delete(L,2);
	_delete(L,4);
	printNode(L);
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值