数据结构4_栈的c语言实现及基本操作

数据结构4_栈

栈:

栈是一种先进先出(Last in First out,LIFO)的操作受限的线性表,只能在一端进出操作,可以进出的一端称为栈顶(top),另一端称为栈底(base)。栈也是以用顺序存储和链式存储两种方式存储;


1 顺序栈:

数据结构4_栈的c语言实现及基本操作_第1张图片

1.1 结构体定义:

动态分配:

typedef struct SqStack{
	ElemType *base;//栈底指针
	ElemType *top;//栈顶指针
}SqStack;

静态分配:

typedef struct SqStack{
	ElemType data[Maxsize];//用数组分配固定内存空间
	int top;
}SqStack;

1.2 基本操作:

1.2.1 顺序栈初始化:

/*分配内存空间并使头尾指针重合*/
bool InitStack(SqStack &S){
	S.base = new int[Maxsize];
	if(!S.base){
		return false;
	}
	S.top = S.base;
	return true;
}

1.2.2 入栈:

/*入栈时先入元素到top所指位置然后top++*/
bool Push(SqStack &S, int e){
	if(S.top - S.base == Maxsize){
		return false;
	}
	*S.top++ = e;
	return true;
}

1.2.3 出栈:

/*出栈是入栈的逆序*/
Elemtype Pop(Sqstack &S){
	Elemtype e;
	if(S.base == S.top) return -1;
	e = *--S.top;
	return e;
}

1.2.4 取栈顶元素:

/*与出栈相比,减少了top--的操作*/
Elemtype GetTop(Sqstack &S){
	Elemtype e;
	if(S.base == S.top) return -1;
	e = *(S.top-1);
	return e;
}

使用静态分配的栈操作与上大同小异;

2. 栈的链式存储:

2.1 结构体定义:

typedef struct Linknode{
	ElemType data;
	struct Linknode *next;
}Linknode,*LinkStack;

插入删除和链表类似,但是只能在栈顶操作,这里只介绍入栈,请类比自己写出出栈操作:

2.2 初始化和出栈:

/*初始化*/
bool InitStack(LinkStack &S){
	S = NULL;
	return true;
}
/*不带头结点的链栈入栈*/
bool Push(LinkStack &S, int e){
	LinkStack p = new Linknode;
	p -> data = e;
	p -> next = S;
	S = p;
	return true;
}
/*带头结点的链栈入栈*/
bool Push(LinkStack &S, int e){
	LinkStack p = new Linknode;
	p -> data = e;
	p -> next = S -> next;
	S -> next = p; //与不带头节点的区别是S不存储元素,且指向实际栈顶
	return true;
}

顺序栈和链栈在基本操作上都只需要常数时间,所以在时间效率上难分伯仲。在空间效率上,顺序栈需要预先分配固定长度的空间,有可能造成空间浪费或者溢出,但是链栈每次只分配一个结点的空间,所以不会出现溢出,但是每个结点需要额外的指针域,空间开销增大。因此,如果元素个数比较多,则选择链栈,反之选择顺序栈,但一般情况下顺序栈足以解决问题。

其次,栈的先进先出是人为规定的,而且我们的简单实现中没有实现从中间取出元素所对应的禁止操作,所以可以从中间取出元素,但是在使用一些语言封装好的数据结构时一般不允许操作中间元素。

你可能感兴趣的:(数据结构与算法,数据结构,栈,c语言,c++,算法)