数据结构:双向链表

一、定义:

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

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

二、功能

双线链表结构体

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;
}
}
相关推荐
Pniubi3 小时前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
nice_lcj5203 小时前
LRU 缓存入门:它是什么、怎么用、面试怎么手写
java·数据结构·缓存·面试·lru
꧁细听勿语情꧂4 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
Pniubi16 小时前
关于算法用现成数据结构和手撕
数据结构
老师我太想进步了20261 天前
【数据结构-6】算法美学之单链表(1)
数据结构·算法
希望我万事顺遂1 天前
力扣hot100-滑动窗口最大值
数据结构·算法·leetcode
꧁细听勿语情꧂1 天前
二叉树余题,排序、直接插入排序、希尔排序
c语言·开发语言·数据结构·算法
是main不是漫1 天前
【双指针|LeetCode1089 复写零】巧用逆向思路,破解原地覆盖陷阱
数据结构·算法·leetcode
饮水桶_T2 天前
JAVA IO流笔记
开发语言·数据结构·算法
wo_jack2 天前
C++ 入门笔记(十七):list 入门 —— 为什么 list 不能 sort?
数据结构·c++·面试·stl·list