数据结构(三)

1、链表 – 单向链表

​ 顺序表:

​ 查找、修改效率高

​ 插入和删除效率低

​ 空间利用率低

​ 链表:

​ 插入和删除效率高

​ 查找、修改效率低

​ 空间利用率高

1、链表节点的相关表示:
typedef int data_t;
typedef struct node
{
	data_t data;
    struct node *next;  
}Linklist;

​ 有头链表:第一个节点的数据无效

​ 无头链表:第一个节点的数据有效

2、单向循环链表

单向循环链表是在单向链表的基础上,将单向链表的最后一个有效节点的next指向第一个节点

3、双向循环链表

相关结构体定义:

typedef int data_t;
typedef struct node
{
	data_t data;   		 //数据域
    struct node *next;   //指向当前节点的下一个节点地址
    struct node *prior;  //指向当前节点的上一个节点地址
}Dlinklist;

作业:

​ 1、完成单向链表的剩余功能(查找、修改、清空、销毁)

​ 2、用单向循环链表完成约瑟夫环的输出(需要提交)

​ 3、完成双向循环链表的剩余功能(删除、修改、查找、清空、销毁)


linklist

/*===============================================
*   文件名称:main.c
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#include "linklist.h"

int main(int argc, char *argv[])
{ 
	int n = 10;
	
	Linklist *head = Linklist_Create();
	
	while(n--)
	{
		Linklist_Insert_Head(head, n);
	}

	Linklist_Show(head);
	
	Linklist_Insert_Pos(head, 0, 100);
	
	Linklist_Show(head);
	
	Linklist_Insert_Pos(head, 1, 99);
	
	Linklist_Show(head);
	
	Linklist_Delete_Pos(head, 0);
	Linklist_Show(head);
	
	Linklist_Delete_Pos(head, 7);
	Linklist_Show(head);	
	
	Linklist_Reverse(head);	
	Linklist_Show(head);
    return 0;
} 
		
/*===============================================
*   文件名称:linklist.c
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#include "linklist.h"

//创建链表
Linklist *Linklist_Create()
{
	Linklist *head = (Linklist *)malloc(sizeof(Linklist)); //在堆区给当前节点开辟空间
	if(NULL == head)
	{
		printf("malloc failed!\n");
		return NULL;
	}
	
	//head->data = -1;  //初始化data数值,在无头链表的头节点中该值不重要	
	head->next = NULL;
		
	return head;	//返回头节点的地址
}

//计算表长
int Linklist_Get_Length(Linklist *head)
{
	int len = 0;
	Linklist *p = head->next;
	while(p != NULL)
	{
		len++;
		p = p->next;
	}
	return len;
}

//判空
int Linklist_Is_Empty(Linklist *head)
{
	if(head->next == NULL)
	{
		//printf("linklist is empty\n");
		return 1;
	}
	else
	{
		return 0;
	}

}

//头部插入
void Linklist_Insert_Head(Linklist *head, data_t data)
{
	Linklist *new = (Linklist *)malloc(sizeof(Linklist)); //在堆区给当前节点开辟空间
	if(NULL == new)
	{
		printf("malloc failed!\n");
		return;
	}	
	new->data = data;
	new->next = NULL;
	
	//插入操作
	new->next = head->next;
	head->next = new;

	return;
}

//按位置插入
void Linklist_Insert_Pos(Linklist *head, int pos, data_t data)
{
	Linklist *p = head;   //将头节点赋值给指针p,用指针p完成遍历操作
	int len = Linklist_Get_Length(head);   //得到表长
	
	if(pos < 0 || pos > len)    //判断pos范围是否有效
	{
		printf("pos error!\n");
		return;
	}
	
	Linklist *new = (Linklist *)malloc(sizeof(Linklist)); //在堆区给当前节点开辟空间
	if(NULL == new)
	{
		printf("malloc failed!\n");
		return;
	}	
	new->data = data;      //初始化新的节点
	new->next = NULL;
	
	for(int i = 0; i < pos; i++)  //找到要插入节点的前一个节点地址
	{
		p = p->next;
	}
	
	new->next = p->next;   //完成插入操作
	p->next = new;
	
	return;
}

//按位置删除
void Linklist_Delete_Pos(Linklist *head, int pos)
{
	if(Linklist_Is_Empty(head) == 1)
	{
		printf("linklist is empty!\n");
		return;
	}

	int len = Linklist_Get_Length(head);

	if(pos < 0 || pos > len-1)
	{
		printf("pos error!\n");
		return;
	}	
	
	Linklist *p = head;
	for(int i = 0; i < pos; i++)   //找到要删除节点的前一个节点地址
	{
		p = p->next;
	}
	
	Linklist *q = p->next;  //记录要删除节点的地址
	
	p->next = q->next;     //删除操作
	free(q);       	//释放删除节点的地址空间
	q = NULL;
	
	return;
}




//打印表
void Linklist_Show(Linklist *head)
{
	Linklist *p = head->next;
	while(p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}


//逆序
void Linklist_Reverse(Linklist *head)
{
	Linklist *p = head->next;
	head->next = NULL;
	Linklist *q = NULL;
	 
	while(p != NULL)
	{
		q = p->next;  
		p->next = head->next;
		head->next = p;	        
		p = q;
	}	
}
/*===============================================
*   文件名称:linklist.h
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#ifndef __LINKLIST_H__
#define __LINKLIST_H__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef int data_t;
typedef struct node
{
	data_t data;  //数据域,用于存放数据
	struct node *next;   //指针域,用于存放下一个节点的地址
}Linklist;

//创建链表
Linklist *Linklist_Create();   

//计算表长
int Linklist_Get_Length(Linklist *head);

//判空
int Linklist_Is_Empty(Linklist *head);

//头部插入
void Linklist_Insert_Head(Linklist *head, data_t data);

//按位置插入
void Linklist_Insert_Pos(Linklist *head, int pos, data_t data);

//按位置删除
void Linklist_Delete_Pos(Linklist *head, int pos);

//打印表
void Linklist_Show(Linklist *head);

//逆序
void Linklist_Reverse(Linklist *head);


#endif
clinklist

/*===============================================
*   文件名称:main.c
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#include "clinklist.h"

int main(int argc, char *argv[])
{ 
	int n = 10;
	
	Linklist *head = Linklist_Create();
	
	while(n--)
	{
		Linklist_Insert_Head(head, n);
	}

	Linklist_Show(head);
	
	Linklist_Insert_Pos(head, 0, 100);
	
	Linklist_Show(head);
	
	Linklist_Insert_Pos(head, 1, 99);
	
	Linklist_Show(head);
	
	Linklist_Delete_Pos(head, 0);
	Linklist_Show(head);
	
	Linklist_Delete_Pos(head, 7);
	Linklist_Show(head);	
	
	Linklist_Reverse(head);	
	Linklist_Show(head);
    return 0;
} 
/*===============================================
*   文件名称:linklist.c
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#include "clinklist.h"

//创建链表
Linklist *Linklist_Create()
{
	Linklist *head = (Linklist *)malloc(sizeof(Linklist)); //在堆区给当前节点开辟空间
	if(NULL == head)
	{
		printf("malloc failed!\n");
		return NULL;
	}
	
	//head->data = -1;  //初始化data数值,在无头链表的头节点中该值不重要	
	head->next = head;
		
	return head;	//返回头节点的地址
}

//计算表长
int Linklist_Get_Length(Linklist *head)
{
	int len = 0;
	Linklist *p = head->next;
	while(p != head)
	{
		len++;
		p = p->next;
	}
	return len;
}

//判空
int Linklist_Is_Empty(Linklist *head)
{
	if(head->next == head)
	{
		//printf("linklist is empty\n");
		return 1;
	}
	else
	{
		return 0;
	}

}

//头部插入
void Linklist_Insert_Head(Linklist *head, data_t data)
{
	Linklist *new = (Linklist *)malloc(sizeof(Linklist)); //在堆区给当前节点开辟空间
	if(NULL == new)
	{
		printf("malloc failed!\n");
		return;
	}	
	new->data = data;
	new->next = NULL;
	
	//插入操作
	new->next = head->next;
	head->next = new;

	return;
}

//按位置插入
void Linklist_Insert_Pos(Linklist *head, int pos, data_t data)
{
	Linklist *p = head;   //将头节点赋值给指针p,用指针p完成遍历操作
	int len = Linklist_Get_Length(head);   //得到表长
	
	if(pos < 0 || pos > len)    //判断pos范围是否有效
	{
		printf("pos error!\n");
		return;
	}
	
	Linklist *new = (Linklist *)malloc(sizeof(Linklist)); //在堆区给当前节点开辟空间
	if(NULL == new)
	{
		printf("malloc failed!\n");
		return;
	}	
	new->data = data;      //初始化新的节点
	new->next = NULL;
	
	for(int i = 0; i < pos; i++)  //找到要插入节点的前一个节点地址
	{
		p = p->next;
	}
	
	new->next = p->next;   //完成插入操作
	p->next = new;
	
	return;
}

//按位置删除
void Linklist_Delete_Pos(Linklist *head, int pos)
{
	if(Linklist_Is_Empty(head) == 1)
	{
		printf("linklist is empty!\n");
		return;
	}

	int len = Linklist_Get_Length(head);

	if(pos < 0 || pos > len-1)
	{
		printf("pos error!\n");
		return;
	}	
	
	Linklist *p = head;
	for(int i = 0; i < pos; i++)   //找到要删除节点的前一个节点地址
	{
		p = p->next;
	}
	
	Linklist *q = p->next;  //记录要删除节点的地址
	
	p->next = q->next;     //删除操作
	free(q);       	//释放删除节点的地址空间
	q = NULL;
	
	return;
}




//打印表
void Linklist_Show(Linklist *head)
{
	Linklist *p = head->next;
	while(p != head)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}


//逆序
void Linklist_Reverse(Linklist *head)
{
	Linklist *p = head->next;
	head->next = NULL;
	Linklist *q = NULL;
	 
	while(p != head)
	{
		q = p->next;  
		p->next = head->next;
		head->next = p;
		p = q;
	}	
}
/*===============================================
*   文件名称:linklist.h
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#ifndef __LINKLIST_H__
#define __LINKLIST_H__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef int data_t;
typedef struct node
{
	data_t data;  //数据域,用于存放数据
	struct node *next;   //指针域,用于存放下一个节点的地址
}Linklist;

//创建链表
Linklist *Linklist_Create();   

//计算表长
int Linklist_Get_Length(Linklist *head);

//判空
int Linklist_Is_Empty(Linklist *head);

//头部插入
void Linklist_Insert_Head(Linklist *head, data_t data);

//按位置插入
void Linklist_Insert_Pos(Linklist *head, int pos, data_t data);

//按位置删除
void Linklist_Delete_Pos(Linklist *head, int pos);

//打印表
void Linklist_Show(Linklist *head);

//逆序
void Linklist_Reverse(Linklist *head);


#endif

dlinlist

/*===============================================
*   文件名称:main.c
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#include "dlinklist.h"

int main(int argc, char *argv[])
{ 
	Dlinklist *head = Dlinklist_Create();  


	for(int i = 0; i < 10; i++)
	{
		Dlinklist_Insert_Pos(head, i, i); 	
	}
	Dlinklist_Show(head);  //打印双向循环链表
    return 0;
} 
/*===============================================
*   文件名称:dlinklist.c
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#include "dlinklist.h"

//创建双向循环链表
Dlinklist *Dlinklist_Create()  
{
	Dlinklist *head = (Dlinklist *)malloc(sizeof(Dlinklist));
	if(NULL == head)
	{
		printf("malloc failed!\n");
		return NULL;
	}
	head->data = -1;
	head->next = head;
	head->prior = head;
	
	return head;	
}


void Dlinklist_Insert_Pos(Dlinklist *head, int pos, data_t data)
{
	Dlinklist *new = (Dlinklist *)malloc(sizeof(Dlinklist));
	if(NULL == new)
	{
		printf("malloc failed!\n");
		return;
	}
	new->data = data;
	new->next = NULL;
	new->prior = NULL;	

	Dlinklist *p = head;
	for(int i = 0; i < pos; i++)
	{
		p = p->next;
	}
	
	new->prior = p;
	p->next->prior = new;
	new->next = p->next;
	p->next = new;
	
	return;
}


//打印双向循环链表
void Dlinklist_Show(Dlinklist *head)
{
	Dlinklist *p = head->next;
	
	while(p != head)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
	return;
}
/*===============================================
*   文件名称:dlinklist.h
*   创 建 者:     
*   创建日期:2024年03月22日
*   描    述:
================================================*/
#ifndef __DLINKLIST_H__
#define __DLINKLIST_H__

#include <stdio.h>
#include <stdlib.h>

typedef int data_t;
typedef struct node
{
    data_t data;
    struct node *next;   //指向下一个节点的地址
    struct node *prior;  //指向上一个节点的地址

}Dlinklist;

Dlinklist *Dlinklist_Create();  //创建双向循环链表

void Dlinklist_Show(Dlinklist *head);  //打印双向循环链表

void Dlinklist_Insert_Pos(Dlinklist *head, int pos, data_t);  //按位置插入


#endif
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

磁铁的朋友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值