链式表示的栈——链式栈1——内容介绍

【定义】
    采用链式存储方式的栈称为链栈或者链式栈。链栈是由若干个结点组成的,而结点又由数据域和指针域组成。在链栈中,结点的数 据域存储栈中元素值,指针域表示结点元素之间的关系。
    插入和删除元素的一端称为栈顶栈顶由栈顶指针top表示。因为插入和删除操作都在栈顶指针位置进行,因此为了操作上的方便,通常在链栈的第一个结点之前设置一个头结点。栈顶指针top指向头结点。头结点的指针指向链栈的第一个结点,如图所示。
 

最先入栈的元素在链栈的尾端,最后入栈的元素在链栈的栈顶。链栈的操作都是在链表的表头位置进行,因此链栈的基本操作的时间复杂度都为O(1)。
由于链栈采用链式存储结构,不必事先估计栈的最大容量,只要系统有可用空间,可随时为结点申请空间,因此在插入结点时不必考虑栈空间是否已满的问题。使用完结点后,应该释放其空间。

【特点】
最先进栈的元素一定是栈底元素,最后进栈的元素一定是栈顶元素。每次删除的元素是栈顶元素,也就是最后进栈的元素。因此栈是一种后进先出(Last In First Out , LIFO)的线性表。

【存储结构】

typedef int DataType;
typedef struct node 
{
	DataType data;
	struct node *next;
}LStackNode,*LinkStack;

【基本运算】
(1)初始化链栈

void InitStack(LinkStack *top)
{
	if ((*top=(LinkStack)malloc(sizeof(LStackNode)))==NULL)
	{
		exit(-1);
	}
	(*top)->next = NULL;
}

(2)判断链栈是否为空

int StackEmpty(LinkStack top)
{
	if (top->next==NULL)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

(3)将元素e入栈。先动态生成一个结点,用p指向该结点,将元素e赋值给*p结点的数据域,然后将新结点插入到链表的第一个结点之前。把新结点插入到链表中的步骤如下:
        ①p->next=top->next;
        ②top->next=p;

如图所示。
链式表示的栈——链式栈1——内容介绍_第1张图片

int PushStack(LinkStack top, DataType e)
{
	LStackNode *p;
	if ((p=(LStackNode*)malloc(sizeof(LStackNode)))==NULL)
	{
		cout << "内存分配失败!";
		exit(-1);
	}
	p->data = e;
	p->next = top->next;
	top->next = p;
	return 1;
}

 (4)将栈顶元素出栈。出栈操作前,先判断栈是否为空,如果栈为空,则返回表示出栈操作失败;否则将栈顶元素出栈,并将栈顶元素赋值给e,最后释放结点空间,返回1表示出栈操作成功。如图。

链式表示的栈——链式栈1——内容介绍_第2张图片

 

int PopStack(LinkStack top, DataType *e)
{
	LStackNode *p;
	p = top->next;
	if (!p)
	{
		cout << "栈已空!";
		return 0;
	}
	top->next = p->next;
	*e = p->data;
	free(p);
	return 1;
}

(5)取栈顶元素

int GetTop(LinkStack top, DataType *e)

{
	LStackNode *p;
	p = top->next;
	if (!p)
	{
		cout << "栈已空!";
		return 0;
	}

	*e = p->data;
	return 1;
}

(6)求栈的长度


int StackLength(LinkStack top)
{
	LStackNode *p;
	int count = 0;
	p = top;
	while (p->next!=NULL)
	{
		p = p->next;
		count++;

	}
	return count;
}

(7)销毁链栈

void DestoryStack(LinkStack top)
{
	LStackNode *p, *q;
	p = top;
	while (!p)
	{
		q = p;
		p = p->next;
		free(q);

	}
}

 

 

你可能感兴趣的:(数据结构与算法,链式栈,数据结构与算法)