数据结构:单向链表的逆置;双向循环链表;栈,输出栈,销毁栈;顺序表和链表的区别和优缺点;0825

单向链表的逆置

代码如下

复制代码
//12.单向链表 逆置
void reverse_link(link_p H)
{
	//判断入参为空
	if(H==NULL) //判断 入参为空
	{
		printf("入参为空,无法清除单向链表,请检查\n");
		return ;
	}
	//判断单向链表为空
	if(empty_link(H))
        {
                printf("单向链表为空,无法输出,请检查\n");
                return ;
        }

	//H 1 2 3 4 5 6
	//S结点 保留2 3 4 5 6结点
	link_p S=H->next->next;
	H->next->next=NULL;

	//H 1
	//S 2 3 4 5 6
	
	//H 2 1
	//S 3 4 5 6
	link_p prev;
	while(S!=NULL)
	{
		prev=S->next;//prev 保留S 的下一个位置
		//头插结点的操作
		S->next=H->next;//S被头插到 H链表
		H->next=S;
		//循环步长
		S=prev;
	}
}

双向循环链表

1.创建 双向循环链表

2.创建 新结点

  1. 判断 双向循环链表为空

4.头插 双向链表

5.头删 双向链表

6.输出 双向链表

10.尾删

8.按位置插入 双向链表

9.按位置删除 双向链表

代码如下

looplink.c

复制代码
#include"loop.h"

//1.创建 双向循环链表
node_p creat_link()
{
	node_p H=(node_p)malloc(sizeof(node));
	if(H==NULL)//申请失败
	{
		printf("申请失败\n");
		return NULL;
	}
	H->next=H;
	H->prev=H;
	H->data=0;

	return H;
}
//2.创建 新结点
node_p creat_node(int V)
{
	node_p N=(node_p)malloc(sizeof(node));
	if(N==NULL)//申请失败
	{
		printf("申请失败\n");
		return NULL;
	}
	N->next=NULL;
	N->prev=NULL;
	N->data=V;

	return N;
}
//3.判断 双向循环链表为空
int empty(node_p H)
{
	if(H==NULL)//入参为空
	{
		printf("入参为空\n");
		return -1;
	}
	return H->next==H;
}
//4.头插 双向循环链表
void insert_head(node_p H,int V)
{
	if(H==NULL)//入参为空
	{
		printf("入参为空\n");
		return;
	}
	//新建结点
	node_p N=creat_node(V);

	//头插 结点链接
	N->next=H->next;//1
	N->prev=H;//2

	H->next=N;//2
	N->next->prev=N;//4 双向循环 不需要判断了 哈哈
}	
//6.输出 双向循环链表
void show(node_p H)
{
	if(H==NULL)//入参为空
	{
		printf("入参为空\n");
		return;
	}
	if(empty(H))
	{
		printf("链表为空\n");
		return;
	}
	//S结点 循环输出
	node_p S=H->next;
	printf("H ");
	do
	{
		printf("%d ",S->data);
		S=S->next;
	}
	while(S!=H);
	printf("H\n");
}
//8.尾删 双向循环链表
void del_tail(node_p H)
{
	if(H==NULL)//入参为空
	{
		printf("入参为空\n");
		return;
	}
	if(empty(H))
	{
		printf("链表为空\n");
		return;
	}

	//D结点 保留尾结点
	node_p D=H->prev;
	//尾删 指针链接
	H->prev=D->prev;
	D->prev->next=D->next;
	//释放空间
	free(D);
}
//9.按位置插入 双向循环链表
void insert_pos(node_p H,int pos,int V)
{       
	if(H==NULL)//入参为空
	{
		printf("入参为空\n");
		return;
	}
	if(pos<=0)
	{
		printf("插入的位置不合理\n");
		return;
	}
	//S找到pos-1位置
	node_p S=H;
	int i;
	for(int i=0;i<pos-1;i++,S=S->next)
	{
		if(S->next==H)
		{
			printf("插入的位置不合理\n");
			return;
		}
	}
	//插入新结点
	node_p N=creat_node(V);

	//按位置插入 指针链接
	N->next=S->next;//1
	N->prev=S;//2

	N->next->prev=N;//3
	S->next=N;//4
}
//10.按位置删除 双向循环链表
void del_pos(node_p H,int pos)
{
        if(H==NULL)//入参为空
        {
                printf("入参为空\n");
                return;
        }
        if(pos<=0)
        {
                printf("插入的位置不合理\n");
                return;
        }
        //D找到pos位置
        node_p D=H;
        int i;
        for(int i=0;i<pos;i++,D=D->next)
        {
                if(D->next==H)
                {
                        printf("删除的位置不合理\n");
                        return;
                }
        }
	//按位置删除 指针链接
	D->prev->next=D->next;
	D->next->prev=D->prev;
	//释放空间
	free(D);
}

loopmain.c

复制代码
#include"loop.h"
int main()
{
	//1.创建 双向循环链表
	node_p H=creat_link();

	int pos;
	int V;

	//4.头插 双向循环链表
	for(int i=99;i>95;i--)
	{
	insert_head(H,i);
	}

	//6.输出 双向循环链表
	show(H);
	
	//8.尾删 双向循环链表
	del_tail(H);
	//输出
	show(H);

	//9.按位置插入 双向循环链表
	printf("按位置插入 双向循环链表\n");
	printf("插入位置:");
	scanf("%d",&pos);
	printf("插入值:");
	scanf("%d",&V);
	insert_pos(H,pos,V);
	//输出
	show(H);

	//10.按位置删除 双向循环链表
	printf("按位置删除 双向循环链表\n");
	printf("删除位置:");
	scanf("%d",&pos);
	del_pos(H,pos);
	//输出
	show(H);

	return 0;
}

loop.h

复制代码
#ifndef __LOOP_H_
#define __LOOP_H_ 1

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

//双向循环链表 结点的结构体
typedef struct node
{
	struct node *prev;
	struct node *next;
	int data;
}node,*node_p;
//1.创建 双向循环链表
node_p creat_link();
//2.创建 新结点
node_p creat_node(int);
//3.判断 双向循环链表为空
int empty(node_p);
//4.头插 双向循环链表
void insert_head(node_p,int);
//6.输出 双向循环链表
void show(node_p);
//8.尾删 双向循环链表
void del_tail(node_p);
//9.按位置插入 双向循环链表
void insert_pos(node_p,int,int);
//10.按位置删除 双向循环链表
void del_pos(node_p,int);



#endif

1.新建栈

2.数据 压入栈

3.判空

4.判满

5.数据 弹出栈

6.输出栈

7.销毁栈

代码如下

stack.c

复制代码
#include"stack.h"
//1.新建栈
stack_p creat()
{
	stack_p S=(stack_p)malloc(sizeof(struct stack));
	if(S==NULL)//申请空间失败
	{
		printf("申请空间失败\n");
		return NULL;
	}
	S->top=-1;//top初始值-1
	bzero(S,sizeof(S->data));//置0 S->data
	return S;
}
//2.数据 压入栈
void push_stack(stack_p S,int V)
{
	if(S==NULL)//传参为空
	{
		printf("传参为空\n");
		return;
	}
	if(full(S))
	{
		printf("栈满,不可压栈\n");
		return;
	}
	//压栈
	//先加再压
	S->data[++S->top]=V;//运算符优先级 回去看看嘛
}
//3.判空
int empty(stack_p S)
{
	if(S==NULL)//传参为空
        {
                printf("传参为空\n");
                return -1;
        }
	return S->top==-1;
}
//4.判满
int full(stack_p S)
{       
	if(S==NULL)//传参为空
	{
		printf("传参为空\n");
		return -1;
	}
	return S->top==MAX-1;
}
//5.数据 弹出栈
//返回值 元素的值
int pop_stack(stack_p S)
{       
	if(S==NULL)//传参为空
        {
                printf("传参为空,无法进行弹栈\n");
                return -1;
        }
	if(empty(S))//判断栈为空
	{
		printf("栈为空,不能进行弹栈\n");
		return -2;
	}
	//弹栈
	//先弹后减
	return S->data[S->top--];
}
//6.输出栈
void show(stack_p S)
{       
	if(S==NULL)//传参为空
        {
                printf("传参为空,无法进行输出\n");
                return ;
        }
        if(empty(S))//判断栈为空
        {
                printf("栈为空,不能进行输出\n");
                return;
        }
	//输出栈
	for(int i=0;i<=S->top;i++)
	{
		printf("%d ",S->data[i]);
	}
	putchar(10);
}
//7.销毁栈
void free_stack(stack_p S)
{
	if(S==NULL)//传参为空
        {
                printf("传参为空\n");
                return ;
        }
	while(S->top!=-1)
	{pop_stack(S);}
	free(S);
}

main.c

复制代码
#include"stack.h"
int main()
{
	//1.新建栈
	stack_p S= creat();
	//2.数据 压入栈
	for(int i=99;i>95;i--)
	{
	push_stack(S,i);
	}
	//5.数据 弹出栈
	printf("弹栈,弹出的值是%d\n",pop_stack(S));
	//6.输出栈
	show(S);

	//7.销毁栈
	free_stack(S);



	return 0;
}

stack.h

复制代码
#ifndef __STACK_H_
#define __STACK_H_ 1

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

#define MAX 5

typedef struct stack
{
	int data[MAX];
	int top;
}seq_stack,*stack_p;

//1.新建栈
stack_p creat();
//2.数据 压入栈
void push_stack(stack_p,int);
//3.判空
int empty(stack_p);
//4.判满
int full(stack_p);
//5.数据 弹出栈
int pop_stack(stack_p);
//6.输出栈
void show(stack_p);
//7.销毁栈
void free_stack(stack_p);


#endif

运行情况

顺序表和单链表的区别,优缺点

顺序表:内存连续,逻辑连续,优点随机查找效率高;缺点长度有限,插入删除效率低

单链表:内存不连续,逻辑连续,优点长度无限制,插入删除效率高;缺点随机访问效率低

相关推荐
月盈缺2 小时前
学习嵌入式的第二十五天——哈希表和内核链表
学习·链表·散列表
小xin过拟合3 小时前
day20 二叉树part7
开发语言·数据结构·c++·笔记·算法
刘 大 望3 小时前
网络编程--TCP/UDP Socket套接字
java·运维·服务器·网络·数据结构·java-ee·intellij-idea
寻星探路3 小时前
数据结构青铜到王者第三话---ArrayList与顺序表(1)
数据结构
今后1233 小时前
【数据结构】顺序表详解
数据结构·顺序表
啟明起鸣3 小时前
【数据结构】B 树——高度近似可”独木成林“的榕树——详细解说与其 C 代码实现
c语言·开发语言·数据结构
这周也會开心3 小时前
数据结构-ArrayList
数据结构
nonono3 小时前
数据结构——线性表(链表,力扣中等篇,技巧型)
数据结构·leetcode·链表
hrrrrb3 小时前
【数据结构】栈和队列——队列
数据结构