ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【数据结构】顺序栈和链栈的实现

2022-03-18 23:30:19  阅读:182  来源: 互联网

标签:数据结构 top next 链栈 顺序 SElemType printf assoL base


目录

顺序栈        

链栈  

           栈是限定仅在表尾进行插入或者删除操作的线性表。表尾端称为“栈顶(top)”,表头端称为栈底(bottom)。不含元素的空表称为空栈。

        栈的修改按后进先出的原则进行,即后进先出(last in first out)如下图所示 

顺序栈

下面看顺序栈的结构体定义

typedef struct {
	SElemType *base;//栈底指针
	SElemType *top;//栈顶指针
	int stacksize;//当前以分配的存储空间
}SqStack;

这里使用一个指针始终指向栈底,和一个栈顶指针指向栈顶元素的上一个位置。若栈顶指针和栈底指针指向同一个位置(top=base),则表示该栈为空栈。每插入一个元素时,指针top增1。

下面直接看代码,栈的最基础的功能。待补全。

//栈的实现

# include <stdio.h>
# include<stdlib.h>
# define STACK_INIT_SIZE 100 //存储空间初始分配量
# define STACKINCREMENT 10 //存储空间分配增量
# define SElemType int
typedef struct {
	SElemType *base;//栈底指针
	SElemType *top;//栈顶指针
	int stacksize;//当前以分配的存储空间
}SqStack;

void InitStack(SqStack &S) {
	S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if (!S.base) printf("创建失败");
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
}

void createStack(SqStack &S, int num) {
	SElemType  elem;
	printf("请输入元素内容");
	while (num > 0) {
		scanf_s("%d", &elem);//修改SElemType注意修改这里------------
		*(S.top)++ = elem;
		num--;
	}
	printf("创建成功\n");
}

SElemType Get_Top(SqStack &S) {
	SElemType e;
	if (S.base == S.top) {
		printf("抱歉,栈空,无元素");
		return NULL;
	}
	e = *(S.top - 1);
	return e;
}

void Push(SqStack &S, SElemType elem) {
	if (S.top - S.base >= S.stacksize) {//栈满
		S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
		if (!S.base) {
			printf("扩容失败");
		}
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCREMENT;
	}
	*(S.top)++ = elem;
	printf("插入成功");
}

void Pop(SqStack& S) {
	SElemType elem;
	if (S.top == S.base) {
		printf("栈已经空了");
	}
	elem = *--S.top;
	printf("%d已被弹出\n", elem);
	printf("栈顶元素为%d\n", *(--S.top));
	*++S.top;//将头指针上移一个
}

void print(SqStack S) {
	while (*S.top != *S.base) {
		printf("%d ", *S.base++);
	}
	printf("\n");
}

int main() {
	int in = 0;
	int num = 0;
	SElemType elem = 0;
	SqStack S;
	printf("1---创建栈\n");
	printf("2---得到栈顶元素 \n");
	printf("3---插入元素\n");
	printf("4---弹出元素\n");
	printf("11---打印栈\n");
	printf("请输入数字:\n");
	while (in != -1) {
		switch (in){
			case 1:
				InitStack(S);
				printf("请输入个数\n");
				scanf_s("%d", &num);
				createStack(S, num);break;
			case 2:
				printf("栈顶元素是%d\n", Get_Top(S));break;
			case 3:
				printf("请输入插入的元素");
				scanf_s("%d", &elem);//修改SElemType注意修改这里------------
				Push(S, elem);break;
			case 4:
				Pop(S);break;
			case 11:
				print(S);break;
		}
		scanf_s("%d", &in);
	}
	return 0;
}

链栈

        在实现链栈后,其实其就是一个简单的单链表,即插入和删除都只操作最后一个元素即可。

        链栈比顺序栈更灵活一点。即每次插入一个元素时,使用malloc函数申请一个新的空间。删除元素时,我是这样的思路,pop函数传入一个链栈的头指针,该指针指向栈底元素。设栈底元素为a。此时不知道后面有几个元素。假设后面存在元素以abcd的顺序排列。当a的next不为空时(b存在),此时分两种情况。第一种,如果a的next的next不为空。即存在c。则将a的next的next设为空(b的next=null)。此时c就与栈没有关系了。第二种,如果a的next的next为空,即不存在c。则将a的next设为空。此时b与栈就没有关系了。

#include<stdio.h>
#include <malloc.h>
#define ElemType int
typedef struct Node{
	ElemType data;
	Node* next;
}*LinkStack, Node;//链栈


LinkStack InitLinkStack() {
	LinkStack Ls;
	Ls = (LinkStack)malloc(sizeof(Node));
	Ls->next = NULL;
	return Ls;//返回头结点
}

void createLinkStack(LinkStack L, int num) {
	ElemType Edata;
	LinkStack assoL = L;//栈底的副本
	Node* newL;
	printf("请分别输入元素\n");
	while (num > 0) {
		scanf_s("%d", &Edata);
		newL = (Node*)malloc(sizeof(Node));
		newL->next = NULL;
		newL->data = Edata;
		assoL->next = newL;//将新元素给栈顶
		num--;
		assoL = newL;
	}
	//assoL = L;
}

void printStack(LinkStack L) {
	LinkStack assoL = L;//栈底的副本
	while (assoL->next != NULL) {
		assoL = assoL->next;
		printf("%d ", assoL->data);
		
	}
	//assoL = L;
}

void push(LinkStack L, ElemType Edata) {
	LinkStack assoL = L;//栈底的副本
	while (assoL->next != NULL) {
		assoL = assoL->next;
	}//找到栈顶
	Node* newL = (Node*)malloc(sizeof(Node));
	newL->next = NULL;
	newL->data = Edata;
	assoL->next = newL;
	//assoL = L;
}

void pop(LinkStack L) {
	LinkStack assoL = L;//栈底的副本
	if (assoL->next == NULL) {
		printf("栈以空");
		return;
	}
	while (assoL->next != NULL) {
		if (assoL->next->next != NULL) {
			assoL = assoL->next;
		}
		else {
			assoL->next = NULL;
			break;
		}
	}
	printf("弹出成功\n");
}
//获取栈顶元素
ElemType getTop(LinkStack L) {
	Node* assoL = L;
	while (assoL->next != NULL) {
		assoL = assoL->next;
	}
	return assoL->data;
}


int main() {
	LinkStack L = NULL;
	int num = 0;
	int in = 0;
	ElemType data = 0;
	printf("请输入数字:\n");
	printf("1---创建栈:\n");
	printf("2---插入:\n");
	printf("3---弹出:\n");
	printf("4---获取栈顶元素:\n");
	printf("9---打印栈:\n");
	printf("-1---退出:\n");
	while (in != -1) {
		switch (in) {
		case 1:
			L = InitLinkStack();
			printf("请输入元素的个数\n");
			scanf_s("%d", &num);
			createLinkStack(L, num);
			break;

		case 2:
			printf("请输入插入的元素:\n");
			scanf_s("%d", &data);
			push(L, data);
			printf("插入成功\n");
			break;
		case 3:
			pop(L);
			break;
		case 4:
			data = getTop(L);
			printf("栈顶元素:%d\n", data);
			break;
		case 9:
			printf("栈内元素是:\n");
			printStack(L);
			printf("\n");
			break;

		case -1:
			return 0;
		}
		scanf_s("%d", &in);
	}
}

标签:数据结构,top,next,链栈,顺序,SElemType,printf,assoL,base
来源: https://blog.csdn.net/qq_51639901/article/details/123586392

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有