数据结构--链表

链表

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

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

单链表

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;
}
相关推荐
阿昭L5 小时前
leetcode链表相交
算法·leetcode·链表
xiaolang_8616_wjl10 小时前
c++超级细致的基本框架
开发语言·数据结构·c++·算法
LYFlied11 小时前
【每日算法】LeetCode124. 二叉树中的最大路径和
数据结构·算法·leetcode·面试·职场和发展
yyy(十一月限定版)12 小时前
c语言——栈和队列
java·开发语言·数据结构
xu_yule13 小时前
算法基础-背包问题(01背包问题)
数据结构·c++·算法·01背包
蒙奇D索大13 小时前
【数据结构】考研408 | 伪随机探测与双重散列精讲:散列的艺术与均衡之道
数据结构·笔记·学习·考研
budingxiaomoli13 小时前
分治算法-快排
数据结构·算法
dragoooon3413 小时前
[C++——lesson30.数据结构进阶——「红黑树」]
开发语言·数据结构·c++
蓝色汪洋14 小时前
数码串和oj
数据结构·算法
阿昭L15 小时前
leetcode链表是否有环
算法·leetcode·链表