数据结构--链表

链表

用一组任意的存储单元存储线性表的数据元素,可以连续也可以不连续

结点包括两个域:数据域和指针域

单链表

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
//单链表 
typedef int ElemType;
typedef struct node{
	ElemType data;
	struct node *next;
}Node; 
//初始化链表 
Node* initList()
{
	Node *head = (Node*)malloc(sizeof(Node));
	head->data = 0;
	head->next = NULL;
	return head;	
} 
//头插法:将数据插在头结点的后面 
//头插法输出的顺序和输入的顺序时相反的 
void insertHead(Node *L,ElemType e)
{
	Node *p = (Node*)malloc(sizeof(Node));
	p->data = e;
	p->next = L->next;
	L->next = p;	
} 
//找尾巴
Node* Get_tail(Node *L)
{
	Node *p = L;
	while(p->next != NULL)
	{
		p = p->next;	
	}	
	return p;
} 
//尾插法:将数据插在尾结点的后面 
void insertTail(Node *L,ElemType e)
{
	Node *p = (Node*)malloc(sizeof(Node));
	Node* tail = Get_tail(L);
	p->data = e; 
	tail->next = p;
	p->next = NULL;	
}
//在指定位置插入数据
int insertNode(Node *L,int pos,ElemType e)
{
	//用来保存插入位置的前驱节点 
	Node *p = L;
	int i = 0;
	while(i < pos - 1)
	{
		p = p->next;
		i ++;
		if(p == NULL)
		{
			return 0;	
		}	
	}
	//创建新结点 
	Node *q = (Node*)malloc(sizeof(Node));
	q->data = e;
	q->next = p->next;
	p->next = q;
	return 1; 
		
} 
//删除指定位置的结点
int deleteNode(Node *L,int pos)
{
	//要删除结点的前驱 
	Node *p = L;
	int i = 0;
	//遍历链表,找到要删除节点的前驱 
	while(i < pos - 1)
	{
		p = p->next;
		i ++;
		if(p == NULL)
		{
			return 0;	
		}	
	}	
	if(p->next == NULL)
	{
		printf("要删除的结点位置错误\n");
		return 0; 
	}
	//q指向要删除的结点 
	Node *q = p->next;
	//让删除结点的前驱指向要删除结点的后继 
	p->next = q->next;
	//释放要删除结点的内存空间 
	free(q);
	return 1; 
} 
//获取链表元素的个数
int getNum(Node *L)
{
	int i = 0;
	while(L != NULL)
	{
		L = L->next;
		i ++;	
	}	
	return i;
} 
//单链表--反转链表
Node* reverseList(Node *head)
{
	Node *first = NULL;
	Node *second = head->next;
	Node *third;
	while(second != NULL)
	{
		third = second->next;
		second->next = first;
		first = second;
		second = third;	
	} 	
	Node *hd = initList();
	hd->next = first;
	return hd;
}
//单链表--删除链表中间节点(快慢指针)
int delMiddleNode(Node *head)
{
	Node *fast = head->next;
	Node *slow = head;
	
	while(fast != NULL && fast->next != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;	
	}	
	Node *q = slow->next;
	slow->next = q->next;
	free(q);
	return 1;
} 
//遍历链表
void listNode(Node *L)
{
	Node *p = L->next;
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}
//释放链表
void freeNode(Node *L)
{
	Node *p = L->next;//p指向第一个结点 
	Node *q;
	
	while(p != NULL)
	{
		q = p->next;
		free(p);
		p = q;	
	} 
	L->next = NULL;
} 
cpp 复制代码
int main()
{
	Node *List = initList();
	insertHead(List,10);
	insertHead(List,20);
	insertHead(List,30);
	insertTail(List,40);
	insertTail(List,50);
	insertNode(List,2,15);
	insertNode(List,4,15);

	listNode(List);
	printf("链表的数量为%d\n",getNum(List)); 
	Node *reverse = reverseList(List);
	delMiddleNode(reverse);
	listNode(reverse);
	return 0;
}

双链表

cpp 复制代码
/*
双向链表 
*/ 
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;

typedef struct node{
	ElemType data;
	struct node *prev,*next;
}Node; 

//初始化链表
Node* initList()
{
	Node *head = (Node*)malloc(sizeof(Node));
	head->data = 0;
	head->next = NULL;
	head->prev = NULL;	
} 

//头插法
int insertHead(Node* L,ElemType e)
{
	Node *p = (Node*)malloc(sizeof(Node));
	p->data = e;
	p->prev = L;
	p->next = L->next;
	if(L->next != NULL)
	{
		L->next->prev = p;
	}
	L->next = p;
	return 1;	
}
//找尾巴
Node *getTail(Node *L)
{
	Node *p = L;
	while(p->next != NULL)
	{
		p = p->next;	
	}		
	return p;
} 
//尾插法
int insertTail(Node *L,ElemType e)
{
	Node *p = (Node*)malloc(sizeof(Node));
	Node *tail = getTail(L);
	p->data = e;
	p->prev = tail;
	tail->next = p;
	p->next = NULL;
	return 1;
} 
//在指定位置插入数据
void insertPos(Node* L,int pos,ElemType e)
{
	Node *p = L;
	int i = 0;
	while(i < pos - 1)
	{
		p = p->next;
		i ++;
	}
	
	Node *q = (Node*)malloc(sizeof(Node));
	q->data = e;
	p->next->prev = q;
	q->next = p->next;
	p->next = q;
	q->prev = p;
}

//删除节点
int deleteNode(Node *L,int pos)
{
	Node *p = L;
	int i = 0;
	//寻找要删除结点的前驱结点 
	while(i < pos - 1)
	{
		p = p->next;
		i ++;	
	}	
	
	if(p->next == NULL)
	{
		printf("要删除的位置错误\n");	
		return 0;
	} 
	
	Node *q = p->next;
	p->next = q->next;
	q->next->prev = p;
	free(q);
	return 1;
}
//释放链表
void freeNode(Node *L)
{
	Node *p = L->next;
	Node *q;
	
	while(p != NULL)
	{
		q = p->next;
		free(q);
		p = q;	
	}	
	L->next = NULL;
} 
//遍历
void listNode(Node *L)
{
	Node *p = L->next;
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;	
	}	
	printf("\n");
} 
cpp 复制代码
int main()
{
	Node* List = initList();
	insertHead(List,10);
	insertHead(List,20);
	insertTail(List,30);
	insertTail(List,40);
	insertPos(List,3,50);
	listNode(List);
	deleteNode(List,3);
	listNode(List);
	freeNode(List);
	listNode(List);
	return 0;
}
相关推荐
古译汉书1 小时前
嵌入式笔记(个人总结)
数据结构·笔记·stm32·单片机·嵌入式硬件
不许哈哈哈12 小时前
Python数据结构
数据结构·算法·排序算法
sin_hielo14 小时前
leetcode 2872
数据结构·算法·leetcode
AI科技星15 小时前
为什么宇宙无限大?
开发语言·数据结构·经验分享·线性代数·算法
合方圆~小文16 小时前
AI摄像头精准识别技术依赖于深度算法
数据结构·数据库·数码相机·模块测试
松涛和鸣16 小时前
16、C 语言高级指针与结构体
linux·c语言·开发语言·数据结构·git·算法
FuckPatience18 小时前
C# 实现元素索引由1开始的链表
开发语言·链表·c#
小欣加油20 小时前
leetcode 1018 可被5整除的二进制前缀
数据结构·c++·算法·leetcode·职场和发展
无敌最俊朗@20 小时前
链表-力扣hot100-随机链表的复制138
数据结构·leetcode·链表