dataStructureDay070809

目录

链式栈

头文件:

源文件:

测试文件:

结果:

链式队列

头文件:

源文件:

测试文件:

结果:

思维导图


链式栈
        头文件:
#ifndef __LINKSTACK_H__
#define __LINKSTACK_H__

typedef int datatype;

typedef struct Node
{
	union
	{
		datatype data;
		int len;
	};

	struct Node *next;
}LinkStack,*LinkStackPtr;

//创建链式栈
LinkStackPtr stack_create();
//判空
int stack_empty(LinkStackPtr L);
//入栈,头插的方式
int stack_push(LinkStackPtr L,datatype e);
//遍历
void stack_show(LinkStackPtr L);
//出栈,头删的方式
int stack_pop(LinkStackPtr L);
//销毁
void stack_free(LinkStackPtr L);

#endif
        源文件:
#include"linkstack.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//创建链式栈
LinkStackPtr stack_create(){
	LinkStackPtr L = (LinkStackPtr)malloc(sizeof(LinkStack));
	if(NULL==L){
		printf("创建失败\n");
		return NULL;
	}

	//创建成功后,初始化
	L->len = 0;
	L->next = NULL;

	printf("创建成功\n");
	return L;

}
//判空
int stack_empty(LinkStackPtr L){
	//判断条件
	if(NULL==L){
		printf("所给链表不合法\n");
		return -1;
	}

	//如果头结点的next为NULL,说明链表为空
	return L->next == NULL;

}
//入栈,头插的方式
int stack_push(LinkStackPtr L,datatype e){
	if(NULL==L){
		printf("所给链表不合法\n");
		return -1;
	}

	//如果链表合法,将要添加的数据封装进一个节点然后链接
	LinkStackPtr p = (LinkStackPtr)malloc(sizeof(LinkStack));
	if(NULL==p){
		printf("节点创建失败\n");
		return 0;
	}
	p->data = e;
	p->next = NULL;

	//头插操作
	p->next = L->next;
	L->next = p;

	//链表长度的变化
	L->len++;

	printf("%d插入成功\n",L->next->data);
	return 1;

}
//遍历
void stack_show(LinkStackPtr L){
	if(NULL==L|| stack_empty(L)){
		printf("输出失败\n");
		return;
	}

	//如果链表合法,从栈顶到栈底输出
	LinkStackPtr p = L->next;
	while(NULL!=p){
		printf("%d\t",p->data);
		p = p->next;
	}
	putchar(10);
	return;

}
//出栈,头删的方式
int stack_pop(LinkStackPtr L){
	if(NULL==L|| stack_empty(L)){
		printf("出栈失败\n");
		return -1;
	}

	//头删操作
	LinkStackPtr p = L->next; //标记
	printf("%d出栈成功\n",p->data);
	L->next = p->next;//孤立
	//释放
	free(p);
	L->len--;
	//链表长度的变化
	
	return 1;

}
//销毁
void stack_free(LinkStackPtr L){
	if(NULL==L|| stack_empty(L)){
		printf("销毁失败\n");
		return;
	}

	//将所有非头节点出栈
	while(L->next!=NULL){
		stack_pop(L);
	}
	//释放头结点
	free(L);
	L = NULL;
	
	printf("释放成功\n");
	return;

}
        测试文件:
#include"linkstack.h"
#include<stdio.h>

int main(int argc, const char *argv[])
{
	LinkStackPtr L = stack_create();
	if(NULL==L){
		return -1;
	}
	//调用入栈函数
	stack_push(L,6);
	stack_push(L,9);
	stack_push(L,3);
	stack_push(L,4);
	stack_push(L,7);
	stack_push(L,5);
	stack_push(L,1);
	
	//调用遍历函数
	stack_show(L);

	//调用出栈函数
	stack_pop(L);
	stack_pop(L);
	stack_pop(L);

	printf("开始销毁\n");
	//销毁
	stack_free(L);
	L = NULL;

	return 0;
}
        结果:

 

链式队列
        头文件:
#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__

typedef int datatype;
//定义节点类型
typedef struct Node
{
	union 
	{
		datatype data;
		int len;
	};
	
	struct Node *next;
}Node;

//定义链式队列
typedef struct
{
	Node *Head;
	Node *Tail;
}LinkQueue,*LinkQueuePtr;

//创建链式队列
LinkQueuePtr list_create();
//判空
int list_empty(LinkQueuePtr LQ);
//创建节点
Node *linklist_create(datatype e);
//入队,采用尾插方式
int list_push(LinkQueuePtr LQ,datatype e);
//出队,采用头删方式
int list_pop(LinkQueuePtr LQ);
//按顺序展示队列元素
void list_show(LinkQueuePtr LQ);
//销毁队伍
void list_free(LinkQueuePtr LQ);

#endif
        源文件:
#include"linkqueue.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//创建链式队列
LinkQueuePtr list_create(){
	//创建一个链式队列的结构体,并在堆区申请空间
	LinkQueuePtr LQ = (LinkQueuePtr)malloc(sizeof(LinkQueue));
	if(NULL==LQ){
		printf("队列创建失败\n");
		return NULL;
	}
	//创建成功的话,说明里面有两个指针
	//LQ->Head,LQ->Tail是野指针
	//创建头结点并在堆区申请空间
	Node *L = (Node *)malloc(sizeof(Node));
	if(NULL==L){
		printf("头结点创建失败\n");
		return NULL;
	}
	//如果成功需要对链表进行初始化
	//头结点的初始化
	L->len = 0;
	L->next = NULL;

	//链式队列的初始化
	LQ->Head = L;
	LQ->Tail = L;

	printf("队列创建成功\n");
	return LQ;

}
//判空
int list_empty(LinkQueuePtr LQ){
	//判断逻辑
	if(NULL==LQ|| NULL==LQ->Head){
		printf("所给队列不合法\n");
		return 0;
	}

	return LQ->Head==LQ->Tail;

}
//创建节点
Node *linklist_create(datatype e){
	//申请一个节点
	Node *p = (Node *)malloc(sizeof(Node));
	if(NULL==p){
		printf("入队失败\n");
		return NULL;
	}

	//存入要存储的数据
	p->data = e;
	p->next = NULL;

	return p;

}
//入队,采用尾插方式
int list_push(LinkQueuePtr LQ,datatype e){
	//判断逻辑
	if(NULL==LQ){
		printf("所给队列不合法\n");
		return 0;
	}

	//创建一个保存有e的节点,申请节点封装数据
	Node *p = linklist_create(e);

	//将新节点连接到队尾指针指向的节点后面
	LQ->Tail->next = p; //尾插,让链表中原来的最后一个节点指向要插入的节点
	LQ->Tail = p;//新的p变成了新的尾,所以要让队列的尾指针指向它

	LQ->Head->len++;//链表长度的变化

	printf("%d入队成功\n",e);
	return 1;

}
//出队,采用头删方式
int list_pop(LinkQueuePtr LQ){
	if(NULL==LQ|| list_empty(LQ)){
		printf("出队失败\n");
		return -1;
	}

	printf("%d出队成功\n",LQ->Head->next->data);
	//如果删除的是链表中除了头结点外的最后一个节点,要让LQ->Tail指向头结点
	//表示队列已经空了
	if(LQ->Head->next==LQ->Tail){
		LQ->Tail = LQ->Head;
	}
	//头删操作
	Node *p = LQ->Head->next; //标记
	LQ->Head->next = p->next; //孤立
	free(p);
	p = NULL; //释放

	//链表长度的变化
	LQ->Head->len--;

	//判断队伍是否已经删除完所有节点
	/*
	   if(LQ->Head->next == NULL){
	//将尾指针重新指向头结点
	LQ->Tail = LQ->Head;
	}
	*/
	return 1;

}
//按顺序展示队列元素
void list_show(LinkQueuePtr LQ){
	if(NULL==LQ|| list_empty(LQ)){
		printf("展示失败\n");
		return ;
	}

	//从头结点的下一个节点开始遍历输出
	//定义一个遍历指针,初始指向第一个元素所在的节点,即头结点的下一个节点,
	Node *p = LQ->Head->next;
	while(NULL!=p){
		printf("%d\t",p->data);
		p = p->next;
	}

	putchar(10);
	return;

}
//释放
void list_free(LinkQueuePtr LQ){
	if(NULL==LQ){
		printf("释放失败\n");
		return;

	}
	//释放整个链表
	while(!list_empty(LQ)){
		list_pop(LQ);
	}
	//释放头结点
	//循环出列结束后,此时队列为空,头指针和尾指针都指向头结点
	free(LQ->Head);
	LQ->Head = NULL;
	LQ->Tail = NULL;
	//头结点也释放结束,只需再将队列释放即可
	free(LQ);
	LQ = NULL;
	printf("释放成功\n");
	return;
}
        测试文件:
#include"linkqueue.h"
#include<stdio.h>

int main(int argc, const char *argv[])
{
	LinkQueuePtr LQ = list_create();
	if(NULL==LQ){
		return -1;
	}

	//调用入队函数
	list_push(LQ,1);
	list_push(LQ,2);
	list_push(LQ,3);
	list_push(LQ,4);
	list_push(LQ,5);
	list_push(LQ,6);
	list_push(LQ,7);
	list_push(LQ,8);
	list_push(LQ,9);
	list_push(LQ,10); 

	//调用出队函数
	list_pop(LQ);
	list_pop(LQ);

	//调用遍历函数
	list_show(LQ);

	//调用释放函数
	list_free(LQ);
	LQ = NULL;

	return 0;
}
        结果:

思维导图

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值