数据结构--顺序栈的c语言实现

Stack(堆栈):一种操作受限制的线性表,只允许在一头进行添加和删除

定义:
        · “栈”也叫“堆栈”,是一种操作受限的线性表,栈只允许在线性表的一端进行插入/删除等操作,不允许其他位置插入/删除
        · 线性表中可以进行插入/删除的一端称为:栈顶(top),栈顶保存的元素为“栈顶元素”,相对另一端称为“栈底”(bottom)
        · 如果栈中没有数据称为“空栈”
        · 向栈中插入元素,称为“进栈/入栈/压栈”,从栈中删除元素称为“退栈/出栈/弹栈”;
        · 栈的插入/删除操作只允许在栈顶进行,后进栈的元素必定先出栈,称为:后进先出表LIFO;

堆栈抽象数据类型的定义:
    ADT Stack{
        数据对象 : D={a0,a1,a2...,an, 其中ai(i=1,2..n)是同一种数据类型的元素}
        数据关系 : R={<ai,ai+1>}
        基本操作:
            InitStack(&S):        初始化栈,分配内存空间
            DestroyStack(&S):    销毁并释放栈的内存
            ClearStack(&S):        清空栈
            IsEmpty(S):            判断栈是否为空
            GetSize(S):            返回栈元素个数
            Peek(S):            偷看栈顶元素
            Push(&S,e):            压栈、入栈
            Pop(&S,&e):            弹栈、出栈
            Traverse(S):        从栈底到栈顶依次遍历
    }ADT Stack;

卡特兰数:如果有n个不同元素进栈,出栈元素不同的排列的个数为:1/(n+1)    *    Cⁿ2n

(还有一种栈叫“共享栈”,逻辑上是2个栈,物理上共享一片连续的内存)
--------------------------
栈的顺序实现:顺序栈一般通过数组实现;堆栈的操作都在栈顶完成,选择数组中索引值较大的一端作为栈顶,也就是数组尾部作为栈顶;

#include <stdlib.h>
#include <stdio.h>
#define ElemType int
#define MAXSIZE 10

typedef struct Stack{
	int capacity;
	int top;
	ElemType* data;
}Stack;

// 空指针异常,用于判断表指针是否为NULL
static void NullPointerException(Stack *s){
	if(s == NULL){exit(1);}
}

//栈扩容(2倍扩容)
static void ExpandSize(Stack *s){
	NullPointerException(s);

	// 临时指针old,保存旧栈的基地址
	ElemType* old = s->data;

	// 申请一片新的空间,是原容量的2倍
	s->capacity *= 2;// 先设置表容量为原来的2倍
	// 直接将表指针指向新容量的地址
	s->data = (ElemType*)malloc(s->capacity * sizeof(ElemType));
	// 如果申请失败,程序直接终止
	if(s->data == NULL){ exit(1); }

	// 申请成功,将旧表的内容进行拷贝
	int i;
	for(i=0; i<s->top; i++){
		s->data[i] = old[i];
	}

	// 销毁旧表
	free(old);
}

//InitStack(&S):		初始化栈,分配内存空间
void InitStack(Stack* s){
	NullPointerException(s);

	s->data = (ElemType*) malloc(MAXSIZE * sizeof(ElemType));
	if(s->data == NULL){ exit(1); }else{//分配成功
		s->capacity = MAXSIZE;
		s->top = 0;
	}
}

//DestroyStack(&S):		销毁并释放栈的内存
void DestroyStack(Stack* s){
	NullPointerException(s);

	s->capacity = 0;
	s->top = 0;
	free(s->data);
	s->data = NULL;
}

//ClearStack(&S):		清空栈
void ClearStack(Stack* s){
	NullPointerException(s);

	s->top = 0;
}

//IsEmpty(S):			判断栈是否为空
int IsEmpty(Stack s){
	return s.top == 0;
}

// GetSize(S):			返回栈元素个数
int GetSize(Stack s){
	return s.top;
}

// Peek(S):			偷看栈顶元素
ElemType Peek(Stack s){
	if(s.top == 0){ exit(1); }
	return s.data[s.top-1];
}

// Push(&S,e):			将e压栈
void Push(Stack* s, ElemType e){
	NullPointerException(s);

	//容量不够,2倍扩容
	if(s->top > s->capacity){
		ExpandSize(s);
	}

	s->data[s->top] = e;
	s->top ++;
}

// Pop(&S,&e):			弹栈
void Pop(Stack* s, ElemType* e){
	NullPointerException(s);

	if(s->top == 0){
		printf("弹栈失败:栈空!\n");
		exit(1);
	}

	s->top --;
	*e = s->data[s->top];
}

// Traverse(S):		从栈底到栈顶依次遍历
void Traverse(Stack s){
	printf("\n");

	int i;
	for(i=0; i<s.top; i++){
		printf("%d  ", s.data[i]);
	}

	printf("\n");
}
//=============测试程序==============================================================
int main(int argc, char const *argv[])
{
	Stack s;
	InitStack(&s);

	Push(&s, 8);
	Push(&s, 18);
	Push(&s, 28);

	ElemType value;
	Pop(&s, &value);
	//看下弹出的东西
	printf("%d\n", value);

	Push(&s, 38);
	Push(&s, 48);
	//看下栈顶
	printf("%d\n", Peek(s));
	Traverse(s);
	printf("栈中元素个数为:%d\n", GetSize(s));

	Pop(&s, &value);
	Pop(&s, &value);
	Traverse(s);
	printf("%d\n", value);

	ClearStack(&s);
	printf("栈是否为空:%d\n", IsEmpty(s));
	Traverse(s);

	DestroyStack(&s);
	return 0;
}

运行结果:

部分代码还可以完善,欢迎指正~_~

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值