0719|数据结构day5(双向链表+双向循环链表)

目录

一、思维导图

二、作业

2.1 单向链表简单选择排序

2.2 单向链表按元素插入

2.3 单向链表按元素修改

三、双链表

 3.1 双向链表结构体建立

3.2 双向链表节点创建

3.3 双向链表头插

3.4 双向链表尾插

3.5 双向链表头删

3.6 双向链表尾删

3.7 双向链表遍历

3.8 双链表全部代码

四、双向循环链表

 4.1 双向循环链表结构体建立

4.2 双向循环链表节点创建

4.3 双向循环链表头插

4.4 双向循环链表尾插

4.5 双向循环链表头删

4.6 双向循环链表尾删

4.7 双向循环链表遍历

4.8 双向循环链表所有代码


一、思维导图

0719|数据结构day5(双向链表+双向循环链表)_第1张图片

二、作业

2.1 单向链表简单选择排序

/*
 * function:    简单选择排序
 * @param [ in] 
 * @param [out] 
 * @return      
 */
void paixu(Linklist L)
{
	//判断链表是否为空
	//判断链表只有有一个节点
	if( NULL==L || L->next==NULL )
	{
		return;
	}
	int i,j;
	int len=Len_linklist(L);
	Linklist p=L;
	Linklist k=NULL;
	for(i=0;inext)
		{
			if(q->data < p->data)
			{
				k=p;
			}
		}
		if(k != q)
		{
			datatype t=k->data;k->data=q->data;q->data=t;
		}
	}
}

2.2 单向链表按元素插入

/*
 * function:    按元素插入
 * @param [ in] 
 * @param [out] 
 * @return      
 */
Linklist insert_by_data(datatype key,datatype e,Linklist L)
{
	int insert_pos=search_by_data(key,L);
	if(insert_pos==-1)
		return L;
	L=insert_by_pos(insert_pos,e,L);
	return L;
}

2.3 单向链表按元素修改

/*
 * function:    按元素修改
 * @param [ in] 
 * @param [out] 
 * @return      
 */
Linklist modify_by_data(datatype key,datatype e,Linklist L)
{
	int modify_pos=search_by_data(key,L);
	if(modify_pos==-1)
		return L;
	L=modify_by_pos(modify_pos,e,L);
	return L;
}

三、双链表

        单向链表只可以向后遍历,使用起来不方便,那么引出双向链表,可以向前遍历。

0719|数据结构day5(双向链表+双向循环链表)_第2张图片

 3.1 双向链表结构体建立

typedef char datatype[20];
typedef struct Node
{
	//数据域
	datatype data;
	//指针域:下一节点地址
	struct Node *next;
	//指针域:上一节点地址
	struct Node *prev;
}*DouleLink;

3.2 双向链表节点创建

/*
 * function:    申请节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink  create_node()
{
	DouleLink node=(DouleLink)malloc(sizeof(struct Node));
	if(NULL==node)
	{
		return NULL;
	}
	strcpy(node->data,"");
	node->next=node->prev=NULL;
	return node;
}

3.3 双向链表头插

0719|数据结构day5(双向链表+双向循环链表)_第3张图片

/*
 * function:    头插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_head(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	//
	strcpy(s->data,e);
	if(NULL!=L)
	{
		s->next=L;
		L->prev=s;
	}
	L=s;
	return L;
}

3.4 双向链表尾插

0719|数据结构day5(双向链表+双向循环链表)_第4张图片

/*
 * function:    尾插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_rear(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	strcpy(s->data,e);
	//2.链表为空
	if(NULL==L)
	{	
		L=s;
		return L;
	}
	//3.已有多个节点
	//找到尾部节点
	DouleLink rear=L;
	while(rear->next!=NULL)
	{
		rear=rear->next;
	}
	rear->next=s;
	s->prev=rear;
	return L;
}

3.5 双向链表头删

0719|数据结构day5(双向链表+双向循环链表)_第5张图片

/*
 * function:    头删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_head(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink q=L->next;
	strcpy(L->data,q->data);
	L->next=q->next;
	if(q->next!=NULL)
		q->next->prev=L;
	free(q);
	q=NULL;
	return L;
}

3.6 双向链表尾删

0719|数据结构day5(双向链表+双向循环链表)_第6张图片

/*
 * function:    头删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_head(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink q=L->next;
	strcpy(L->data,q->data);
	L->next=q->next;
	if(q->next!=NULL)
		q->next->prev=L;
	free(q);
	q=NULL;
	return L;
}

3.7 双向链表遍历

0719|数据结构day5(双向链表+双向循环链表)_第7张图片

/*
 * function:    循环输出
 * @param [ in] 
 * @param [out] 
 * @return      
 */
void output(DouleLink L)
{
	//1.如果为空
	if(NULL==L)
	{
		return;
	}
	//2.如果存在节点
	//正向遍历
	puts("正向遍历:");
	while(L->next!=NULL)
	{
		printf("%s\t",L->data);
		L=L->next;
	}
	printf("%s\n",L->data);
	//逆向遍历
	puts("逆向遍历:");
	while(L!=NULL)
	{
		printf("%s\t",L->data);
		L=L->prev;
	}
	puts("");
}

3.8 双链表全部代码

double_head.h

#ifndef __HEAD__H__
#define __HEAD__H__

#include 
#include 
#include 

typedef char datatype[20];
typedef struct Node
{
	//数据域
	datatype data;
	//指针域:下一节点地址
	struct Node *next;
	//指针域:上一节点地址
	struct Node *prev;
}*DouleLink;

DouleLink insert_head(datatype e,DouleLink L);
void output(DouleLink L);
DouleLink insert_rear(datatype e,DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_rear(DouleLink L);
#endif

double_main.c

#include "double_head.h"
int main(int argc, const char *argv[])
{
	DouleLink L=NULL;
	int n;
	datatype e;
	printf("please enter n:");
	scanf("%d",&n);
	for(int i=0;i

double_test.c

#include "double_head.h"
/*
 * function:    申请节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink  create_node()
{
	DouleLink node=(DouleLink)malloc(sizeof(struct Node));
	if(NULL==node)
	{
		return NULL;
	}
	strcpy(node->data,"");
	node->next=node->prev=NULL;
	return node;
}


/*
 * function:    头插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_head(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	//
	strcpy(s->data,e);
	if(NULL!=L)
	{
		s->next=L;
		L->prev=s;
	}
	L=s;
	return L;
}

/*
 * function:    循环输出
 * @param [ in] 
 * @param [out] 
 * @return      
 */
void output(DouleLink L)
{
	//1.如果为空
	if(NULL==L)
	{
		return;
	}
	//2.如果存在节点
	//正向遍历
	puts("正向遍历:");
	while(L->next!=NULL)
	{
		printf("%s\t",L->data);
		L=L->next;
	}
	printf("%s\n",L->data);
	//逆向遍历
	puts("逆向遍历:");
	while(L!=NULL)
	{
		printf("%s\t",L->data);
		L=L->prev;
	}
	puts("");
}

/*
 * function:    尾插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_rear(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	strcpy(s->data,e);
	//2.链表为空
	if(NULL==L)
	{	
		L=s;
		return L;
	}
	//3.已有多个节点
	//找到尾部节点
	DouleLink rear=L;
	while(rear->next!=NULL)
	{
		rear=rear->next;
	}
	rear->next=s;
	s->prev=rear;
	return L;
}

/*
 * function:    头删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_head(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink q=L->next;
	strcpy(L->data,q->data);
	L->next=q->next;
	if(q->next!=NULL)
		q->next->prev=L;
	free(q);
	q=NULL;
	return L;
}

/*
 * function:    尾删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_rear(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink rear=L;
	while(rear->next!=NULL)
		rear=rear->next;

	rear->prev->next=NULL;
	free(rear);
	rear=NULL;
	return L;
}

四、双向循环链表

        因为双向链表在找尾节点是,需要从第一个节点遍历到最后一个节点,时间复杂度高,而且单链表只能向后遍历,不可以向前,所以引出双向循环链表。双向循环链表最大特点是:不需要通过循环找到尾节点,相对方便

0719|数据结构day5(双向链表+双向循环链表)_第8张图片

 4.1 双向循环链表结构体建立

typedef char datatype[20];
typedef struct Node
{
	//数据域
	datatype data;
	//指针域
	struct Node *next;
	//指针域
	struct Node *prev;
}*DouleLink;

4.2 双向循环链表节点创建

0719|数据结构day5(双向链表+双向循环链表)_第9张图片

/*
 * function:    申请节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink  create_node()
{
	DouleLink node=(DouleLink)malloc(sizeof(struct Node));
	if(NULL==node)
	{
		return NULL;
	}
	strcpy(node->data,"");
	node->next=node->prev=NULL;
	return node;
}

4.3 双向循环链表头插

0719|数据结构day5(双向链表+双向循环链表)_第10张图片

/*
 * function:    头插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_head(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	//
	strcpy(s->data,e);
	if(NULL!=L)
	{
		s->next=L;
		L->prev=s;
	}
	L=s;
	return L;
}

4.4 双向循环链表尾插

0719|数据结构day5(双向链表+双向循环链表)_第11张图片

/*
 * function:    尾插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_rear(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	strcpy(s->data,e);
	//2.链表为空
	if(NULL==L)
	{	
		L=s;
		return L;
	}
	//3.已有多个节点
	//找到尾部节点
	DouleLink rear=L;
	while(rear->next!=NULL)
	{
		rear=rear->next;
	}
	rear->next=s;
	s->prev=rear;
	return L;
}

4.5 双向循环链表头删

0719|数据结构day5(双向链表+双向循环链表)_第12张图片

/*
 * function:    头删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_head(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink q=L->next;
	strcpy(L->data,q->data);
	L->next=q->next;
	if(q->next!=NULL)
		q->next->prev=L;
	free(q);
	q=NULL;
	return L;
}

4.6 双向循环链表尾删

0719|数据结构day5(双向链表+双向循环链表)_第13张图片

/*
 * function:    尾删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_rear(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink rear=L;
	while(rear->next!=NULL)
		rear=rear->next;

	rear->prev->next=NULL;
	free(rear);
	rear=NULL;
	return L;
}

4.7 双向循环链表遍历

0719|数据结构day5(双向链表+双向循环链表)_第14张图片

/*
 * function:    循环输出
 * @param [ in] 
 * @param [out] 
 * @return      
 */
void output(DouleLink L)
{
	//1.如果为空
	if(NULL==L)
	{
		return;
	}
	//2.如果存在节点
	//正向遍历
	puts("正向遍历:");
	while(L->next!=NULL)
	{
		printf("%s\t",L->data);
		L=L->next;
	}
	printf("%s\n",L->data);
	//逆向遍历
	puts("逆向遍历:");
	while(L!=NULL)
	{
		printf("%s\t",L->data);
		L=L->prev;
	}
	puts("");
}

4.8 双向循环链表所有代码

head.h

#ifndef __HEAD__H__
#define __HEAD__H__

#include 
#include 
#include 
typedef char datatype[20];

typedef struct Node
{
	//数据域
	datatype data;
	//指针域
	struct Node *next;
	//指针域
	struct Node *prev;
}*DouleLink;

DouleLink insert_head(datatype e,DouleLink L);
void output(DouleLink L);
DouleLink insert_rear(datatype e,DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_head(DouleLink L);
DouleLink delete_rear(DouleLink L);
#endif

main.c

#include "double_head.h"
int main(int argc, const char *argv[])
{
	DouleLink L=NULL;
	int n;
	datatype e;
	printf("please enter n:");
	scanf("%d",&n);
	for(int i=0;i

test.c

#include "double_head.h"
/*
 * function:    申请节点
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink  create_node()
{
	DouleLink node=(DouleLink)malloc(sizeof(struct Node));
	if(NULL==node)
	{
		return NULL;
	}
	strcpy(node->data,"");
	node->next=node->prev=NULL;
	return node;
}


/*
 * function:    头插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_head(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	//
	strcpy(s->data,e);
	if(NULL!=L)
	{
		s->next=L;
		L->prev=s;
	}
	L=s;
	return L;
}

/*
 * function:    循环输出
 * @param [ in] 
 * @param [out] 
 * @return      
 */
void output(DouleLink L)
{
	//1.如果为空
	if(NULL==L)
	{
		return;
	}
	//2.如果存在节点
	//正向遍历
	puts("正向遍历:");
	while(L->next!=NULL)
	{
		printf("%s\t",L->data);
		L=L->next;
	}
	printf("%s\n",L->data);
	//逆向遍历
	puts("逆向遍历:");
	while(L!=NULL)
	{
		printf("%s\t",L->data);
		L=L->prev;
	}
	puts("");
}

/*
 * function:    尾插
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink insert_rear(datatype e,DouleLink L)
{
	//1.创建新节点
	DouleLink s=create_node();
	if(NULL==s)
		return L;
	strcpy(s->data,e);
	//2.链表为空
	if(NULL==L)
	{	
		L=s;
		return L;
	}
	//3.已有多个节点
	//找到尾部节点
	DouleLink rear=L;
	while(rear->next!=NULL)
	{
		rear=rear->next;
	}
	rear->next=s;
	s->prev=rear;
	return L;
}

/*
 * function:    头删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_head(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink q=L->next;
	strcpy(L->data,q->data);
	L->next=q->next;
	if(q->next!=NULL)
		q->next->prev=L;
	free(q);
	q=NULL;
	return L;
}

/*
 * function:    尾删
 * @param [ in] 
 * @param [out] 
 * @return      
 */
DouleLink delete_rear(DouleLink L)
{
	//1.如果链表为空
	if(NULL==L)
		return L;
	//2.判断链表只有一个节点
	if(NULL==L->next)
	{
		free(L);
		L=NULL;
		return L;
	}
	//3.有多个节点
	DouleLink rear=L;
	while(rear->next!=NULL)
		rear=rear->next;

	rear->prev->next=NULL;
	free(rear);
	rear=NULL;
	return L;
}

你可能感兴趣的:(数据结构,链表,数据结构,链表)