数据结构:双向链表

一、定义:

单链表:每一个节点都有一个直接后继,只能单方向查找元素

双向链表:每个节点既有直接前驱也有直接后继,一个指针域指向前驱,一个指针域指向后继

二、功能

双线链表结构体

cs 复制代码
#ifndef __DOUBLE_LIST_H__
#define __DOUBLE_LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int datatype;
typedef struct double_list{
	union{
		int len;
		datatype data;
	};
	struct double_list *next;//指向后继指针
	struct double_list *pri;//指向前驱指针
}double_list,*double_p;

//创建双向循环链表头节点
double_p creat_head();
//创建节点
double_p creat_node(datatype data);
//头插
void insert_head(double_p H,datatype data);
//尾插
void insert_tail(double_p H,datatype data);
//输出
void out_put(double_p H);
//按位置插入
void insert_pos(double_p H,int pos,datatype data);
//尾删
void del_tail(double_p H);
//头删
void del_head(double_p H);
//按位置删除
void del_pos(double_p H,int pos);
//判空
int empty_double(double_p H);
//释放双向链表
void free_double(double_p H);
#endif

1.创建双向链表头节点

cs 复制代码
double_p creat_head(){
	double_p H=(double_p)malloc(sizeof(double_list));
	if(H==NULL){
		printf("空间申请失败\n");
		return NULL;
	}
	H->len=0;
	H->next=NULL;
	H->pri=NULL;
	return H;
}

2.创建节点

cs 复制代码
//创建节点
double_p creat_node(datatype data){
	double_p new=(double_p)malloc(sizeof(double_list));

	if(new==NULL){
		printf("空间申请失败\n");
		return NULL;
	}
	new->data=data;
	return new;//返回申请节点的首地址
}

3.头插

cs 复制代码
//头插
void insert_head(double_p H,datatype data){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	double_p new=creat_node(data);
	if(H->next!=NULL){
		new->pri=H;//新节点的前去指向头节点
		H->next->pri=new;//头节点后继节点的前去指向新节点
		//如果不判断H->next==NUL,H->next->pri会涉及到空指针的间接访问
		new->next=H->next;//新节点的后继指向H的后继
		H->next=new;//一定要最后写
		H->len++;
	}
	else{
		new->next=H->next;
		H->next=new;
		new->pri=H;
		H->len++;
	}
}

4.尾插

cs 复制代码
//尾插
void insert_tail(double_p H,datatype data){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	double_p new=creat_node(data);
	//找到最后一个节点
	double_p p=H;
	while(p->next!=NULL){
		p=p->next;
	}
	new->pri=p;
	new->next=p->next;
	p->next=new;
	H->len++;
}

5.按位置插入

cs 复制代码
//按位置插入
void insert_pos(double_p H,int pos,datatype data){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	//位置合理性判断
	if(pos<=0 || pos>H->len+1){
		printf("位置不合理\n");
		return;
	}
	//找到pos-1位置的节点
	double_p p=H;
	for(int i=0;i<pos-1;i++){
		p=p->next;
	}
	double_p new=creat_node(data);
	new->pri=p;//新节点的前驱指向pos-1
	new->next=p->next;//新节点的后继指向原来pos-1的后继
	if(p->next!=NULL){
		p->next->pri=new;//如果pos位置本身有节点
		//让pos节点的前驱指向新节点
	}
	p->next=new;//pos-1的后继指向新节点
	H->len++;
}

6.输出

cs 复制代码
//输出
void out_put(double_p H){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	double_p p=H->next;
	while(p!=NULL){
		printf("%d ",p->data);
		p=p->next;
	}
	putchar(10);
}

7.尾删

cs 复制代码
//尾删
void del_tail(double_p H){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	double_p p=H;
	while(p->next->next!=NULL){
		p=p->next;
	}
	double_p del=p->next;
	p->next=p->next->next;
	free(del);
	H->len--;
}

8.头删

cs 复制代码
//头删
void del_head(double_p H){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	double_p p=H->next;
	double_p del=p;
	H->next=p->next;
	p->next->pri=H;
	free(del);
	H->len--;
}

9.按位置删除

cs 复制代码
void del_pos(double_p H,int pos){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	if(pos<=0 || pos>H->len){
		printf("位置不合理\n");
		return;
	}
	double_p p=H;
	for(int i=0;i<pos-1;i++){
		p=p->next;
	}
	double_p del=p->next;
	del->next->pri=p;
	p->next=p->next->next;

	free(del);
	H->len--;
}

10.判空

cs 复制代码
int empty_double(double_p H){
	if(H==NULL){
		printf("空间申请失败\n");
		return -1;
	}
return H->next==NULL?1:0;
}

11.释放双向链表

cs 复制代码
//释放双向链表
void free_double(double_p H){
	if(H==NULL){
		printf("空间申请失败\n");
		return;
	}
	if(empty_double(H)){
		printf("链表为空\n");
		return;
	}
//循环头删
double_p p=H->next;
double_p del;
while(p!=NULL){
	del=p;//让del指针保存每次要释放的指针
	p=p->next;
	free(del);
	del=NULL;
}
}
相关推荐
墨染点香42 分钟前
LeetCode 刷题【138. 随机链表的复制】
算法·leetcode·链表
立志成为大牛的小牛4 小时前
数据结构——三十七、关键路径(王道408)
数据结构·笔记·程序人生·考研·算法
Shinom1ya_7 小时前
算法 day 41
数据结构·算法·leetcode
无敌最俊朗@7 小时前
C++ 值类别与移动语义详解(精简版)
java·数据结构·算法
岑梓铭8 小时前
《考研408数据结构》第六章(5.5树的应用)复习笔记
数据结构·笔记·考研·408·ds
不觉晚秋8 小时前
极限挑战之一命速通哈夫曼树
c语言·数据结构··哈夫曼树
第七序章9 小时前
【C + +】C++11 (下) | 类新功能 + STL 变化 + 包装器全解析
c语言·数据结构·c++·人工智能·哈希算法·1024程序员节
仰泳的熊猫9 小时前
LeetCode:72. 超级次方
数据结构·c++·算法·leetcode
yuuki23323310 小时前
【数据结构】单链表的实现
c语言·数据结构·后端
吴名氏.10 小时前
细数Java中List的10个坑
java·开发语言·数据结构·list