C语言数据结构 - 栈

栈的定义

        类似很多软件都有撤销的操作,这其实就是用栈这种方法来实现的,当然不同的软件具体实现代码会有差异,不过原理大多都是一样的。

        栈(stack)是限定仅在表尾进行插入和删除操作的线性表。

        我们把允许插入和删除的一端称为栈顶(top),另一端称为栈低(bottom),不含任何数据元素的栈称为空栈。栈又称为后进后出(Last In First Out)的线性表,简称LIFO结构。

栈的顺序存储结构及实现

         它是顺序表的一种,具有顺序表同样的存储结构,由数组定义,配合用数组下标表示的栈顶指针top(相对指针)完成各种操作。

         我们定义一个top变量来指示栈顶元素在数组中的位置,这top就如同中学物理学过的游标卡尺的游标,如下图所示,它可以来回移动,意味着栈顶的top可以变大变小,但是无论如何游标都不能超出尺的长度。同理,若存储栈的长度为SIZE,则栈顶位置top必须小于SIZE。当栈存在一个元素时,top等于0,因此通常把为空栈的判定条件定为top等于-1;

代码示例:分为SeqStack.c、SeqStack.h、main.c

/*********************************
***********SeqStack.c*************
**********************************/
#include <stdlib.h>
#include <stdio.h> 
#include <string.h>
#include "SeqStack.h"

SqStack* CreatStack()						//初始化操作,建立一个空栈
{
	SqStack* stack = (SqStack* )malloc(sizeof(SqStack));
	
	if(stack == NULL)
	{
		return NULL;
	}
	stack->top = -1;
	memset(stack->data,0,sizeof(stack->data));
	
	return stack;
} 
int Stack_is_Empty(SqStack *s)				//判断栈空 
{
	if(s == NULL)
	{
		return -1;
	} 
	return (s->top == -1);
} 
int Stack_is_Full(SqStack *s)				//判断栈满 
{
	if(s == NULL)
	{
		return -1;
	}
	return ( s->top == (MAXSIZE - 1) );
} 
int StackGetLength(SqStack *s)				//返回栈S的元素个数
{
	if(s == NULL)
	{
		return -1;
	}
	
	return (s->top+1);
} 
int Push(SqStack *s, data_t data)			//压栈,插入新元素data到栈S 
{
	if(Stack_is_Full(s) || s == NULL)
	{
		return -1;
	}
	s->data[s->top+1] = data;
	s->top++;
	
	return 0;
} 
data_t Pop(SqStack *s)						//出栈  从顺序栈中提取数据
{
	data_t data;
	
	if(s == NULL || Stack_is_Empty(s))
	{
		return -1;
	}
	
	data = s->data[s->top];
	s->top--;
	
	return data;
} 
int ClearStack(SqStack *s) 				    //将栈清空
{
	s->top = -1;
} 
int DestroyStack(SqStack *s)				//若栈存在,则销毁它
{
	s->top = -1;
	free(s);
} 
int PrintStack(SqStack *s)				    //打印顺序栈中的数据 
{
	int m = s->top;
	
	if(s == NULL)
	{
		return -1;
	}	
	for(;m >= 0; m--)
	{
		printf("%d\n",s->data[m]);	
	}
	
	return 0;
} 
/*********************************
***********SeqStack.h*************
**********************************/
#ifndef __SEQSTACK_H__
#define __SEQSTACK_H__

#define MAXSIZE 10

typedef int data_t;              //定义栈中数据元素的数据类型 
typedef struct {
	data_t data[MAXSIZE];  
	int top;					 //栈顶指针  表示指向栈顶元素 
}SqStack;


/***************************函数声明*************************************/
SqStack* CreatStack();						//初始化操作,建立一个空栈
int Stack_is_Empty(SqStack *s);				//判断栈空 
int Stack_is_Full(SqStack *s);				//判断栈满 
int StackGetLength(SqStack *s);				//返回栈S的元素个数
int Push(SqStack *s, data_t data);			//压栈,插入新元素data到栈S 
data_t Pop(SqStack *s);						//出栈  从顺序栈中提取数据 
int ClearStack(SqStack *s); 				//将栈清空
int DestroyStack(SqStack *s);				//若栈存在,则销毁它
int PrintStack(SqStack *s);				    //打印顺序栈中的数据 

 
#endif

/*********************************
*************main.c***************
**********************************/
#include <stdio.h>
#include "SeqStack.h"

int main(int argc, char *argv[])
{
	printf("顺序栈测试代码\r\n");
	
	SqStack *seq;
	int i;
	
	seq = CreatStack();

	for(i=0;i<MAXSIZE;i++)
	{
		//入栈 
		Push(seq,i);
	}
	PrintStack(seq);
	
	printf("出栈了\r\n");
	//出栈 
	data_t m = Pop(seq);
	data_t n = Pop(seq);
	printf("m = %d\r\n",m);
	printf("n = %d\r\n",n);
	//打印 
	PrintStack(seq);
	
	//清空栈
	ClearStack(seq); 
	return 0;
}

栈的链式存储结构及实现

        上面介绍了栈的顺序存储结构,下面我们来看看栈的链式存储结构,简称链栈。

        链式栈的插入和删除操作均在链表头部进行(如下图所示),链表尾部就是栈底,栈顶指针就是头指针。

        对于链栈来说,基本不存在栈满的情况,除非内存已经没有可以使用的空间,如果真的发生,那此时的计算机操作系统已经面临死机崩溃的情况,而不是这个链栈是否溢出的问题。

        对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是top等于NULL的时候。

代码示例:分为linkstack.c、linkstack.h、main.c

/*******************************
 ***********linkstack.c*********
 *******************************/
#include "linkstack.h"
#include <stdio.h>
#include <stdlib.h>

lstack * CreateLstack()             //创建链式栈
{
	lstack *top = (lstack *)malloc(sizeof(lstack));
	if(top == NULL)
	{
		return NULL;
	}	
	top->data = -1;
	top->next = NULL;
	
	return top;
}
int Lstack_is_Empty(lstack *top)     // 判断是否为空
{
	if(top == NULL)
	{
		return -1;
	} 
	
	return (top->next == NULL);
}
int LstackgetLength(lstack *top)    //求链式栈当中有效结点数 不包含头结点
{
	int num;
	lstack *p;
	
	if(top == NULL)
	{
		return -1;
	}
	
	p = top->next;
	while(p != NULL)
	{
		p = p->next;
		num++;
	}
	
	return num;
}
int PushLstack(lstack *top,data_t data)//入栈
{
	if(top == NULL)
	{
		return -1;
	}
	
	lstack *new_d = (lstack *)malloc(sizeof(lstack));
	if(new_d == NULL)
	{
		return -1;
	}
	
	new_d->data = data;
	new_d->next = NULL;
	
	new_d->next = top->next;
	top->next = new_d;
	
	return 0; 
}
data_t PoPLstack(lstack *top)         // 出栈
{
	if(top == NULL)
	{
		return -1;
	}
	
	lstack *p = top->next;
	top->next = p->next;
	
	data_t m = p->data;
	free(p);
	p = NULL;
	
	return 0; 
}

int DestoryStack(lstack **top)    //销毁链栈 
{
  if(top == NULL)
    {
        return -1;
    }
    lstack* to_delete = *top;
    while(to_delete != NULL)
    {
        lstack* node = to_delete->next;
        free(to_delete);
        to_delete = node;
    }
    *top = NULL;
    
    return 0;
}

int PrintLstack(lstack *top)     //打印链式栈
{
	if(top == NULL)
	{
		return -1;
	}
	
	lstack *p = top->next;
	while(p != NULL)
	{
		printf("%d\r\n",p->data);
		p = p->next;	
	}
	
	return 0;
}
/*******************************
 ***********linkstack.h*********
 *******************************/
#ifndef __LINKSTACK_H__
#define __LINKSTACK_H__

typedef int data_t;                      //定义栈中元素数据类型

typedef struct node{
	data_t data;                         //数据域
	struct node *next;                   //链栈指针域
}lstack;                                 //链栈类型定义

lstack * CreateLstack();                  //创建链式栈
int Lstack_is_Empty(lstack *top);         // 判断是否为空
int LstackgetLength(lstack *top);         //求链式栈当中有效结点数 不包含头结点
int PushLstack(lstack *top,data_t data);  //入栈
data_t PoPLstack(lstack *top);            // 出栈
int PrintLstack(lstack *top);             // 打印链式栈
int DestoryStack(lstack **top);           //摧毁链栈 

#endif
/*******************************
 *************main.c************
 *******************************/
#include <stdio.h>
#include "linkstack.h"

int main(int argc, char *argv[])
{
	int i;
	lstack *p = CreateLstack();
	
	for(i = 0; i < 10; i++)
	{
		PushLstack(p,i);
	}
	PrintLstack(p);
	//摧毁链栈 
	printf("摧毁链栈S\r\n");
	DestoryStack(&p);
	printf("摧毁链栈E\r\n");
	PrintLstack(p);
	 
	return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
顺序是一种基于数组实现的,它的特点是具有随机存取的特性。顺序的基本运算包括进、出和查看顶元素。进操作将元素插入到顶,出操作将顶元素删除并返回,查看顶元素操作返回顶的元素值,但不修改的状态。 在C语言中,顺序的存储结构可以使用一个一维数组来存放中的元素,同时使用一个指示器top来指示顶的位置。在进行进和出操作时,需要更新top的值,使其指向顶元素。 下面是一种常见的顺序的定义和基本操作的示例代码: ```c // 定义中元素的数据类型 typedef int StackElementType; // 定义顺序的存储结构 #define Stack_Size 100 // 的最大容量 typedef struct { StackElementType elem[Stack_Size]; // 用数组存放中元素 int top; // 顶指针 } SeqStack; // 初始化顺序 void Init_SeqStack(SeqStack *S) { S->top = -1; // 初始时为空,顶指针置为-1 } // 进操作 void Push_SeqStack(SeqStack *S, StackElementType x) { if (S->top == Stack_Size - 1) { printf("已满,无法进"); return; } S->top++; // 顶指针加1 S->elem[S->top] = x; // 将新元素放入顶位置 } // 出操作 StackElementType Pop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空,无法出"); return -1; // 返回一个特殊值表示出错 } StackElementType x = S->elem[S->top]; // 获取顶元素的值 S->top--; // 顶指针减1 return x; // 返回顶元素的值 } // 查看顶元素 StackElementType GetTop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空"); return -1; // 返回一个特殊值表示出错 } return S->elem[S->top]; // 返回顶元素的值 } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值