0
点赞
收藏
分享

微信扫一扫

408数据结构学习笔记——栈

草原小黄河 2022-03-24 阅读 88

目录

1.栈的基本概念

1.1.栈的定义

1.2.栈的基本操作

2.顺序栈栈的基本操作

2.1.顺序栈的初始化

2.2.进栈操作

2.3.出栈操作

2.4.读栈顶元素

2.5.共享栈

3.王道课后题​


1.栈的基本概念

1.1.栈的定义

栈是只允许在一端进行插入或删除的线性表

栈顶:允许进行插入删除的那一段

栈底:不允许进行插入删除的另一端

进栈顺序:1->2->3->4->5

出栈顺序:5->4->3->2->1(后进先出:LIFO)

1.2.栈的基本操作

initStack(&S);    //初始化一个空栈S
stackEmpty(S);    //判断栈空
push(&S, x);    //进栈
pop(&S, &x);    //出栈
getTop(&S, &x);    //读栈顶元素
destroyStack(&S);    //销毁栈

n个不同元素进栈,出栈的不同序列为

2.顺序栈栈的基本操作

2.1.顺序栈的初始化

  1. 采用定义一组地址连续的存储单元存放元素(数组)
  2. 申明一个指针指向当前栈顶元素的位置。栈空时,top的值设置为-1;每加入一个元素,top的值+1,直到栈满,即maxSize - 1(数组的特性,下标从0开始)
#define maxSize 50	//定义栈中的最大元素
typedef  struct {
	elemType data[maxSize];	//静态数组存放栈中元素
	int top;	//栈顶指针
}sqStack;
//初始化栈
void initStack(sqStack &S){
    S.top = -1;    //初始化栈顶指针
}
//判断栈空
bool stackEmpty(sqStack S){
    if (S.top == -1) return true;    //栈空
    else return false;    //栈不空
}
void testStack(){
    sqStack S;
    initStack(S);
    //后续操作
}

 

2.2.进栈操作

//新元素入栈
bool push(sqStack &S, elemType e){
    if(S.top == maxSize - 1) return false;    //栈满,返回false
    else{
        //等价于S.data[++S.top] = x;
        S.top++;    //栈顶指针+1(数组特性)
        S.data[S.top] = x;    //新元素入栈
        return true
    }
}

2.3.出栈操作

出栈操作数据实际上还存在于数组中,即内存还存有数据,但是逻辑上删除了

//出栈
bool pop(sqStack &S, elemType &e){
    if (S.top == -1) return false;    //栈空,返回false
    else {
        x = S.data[top--];    //先将x从栈顶取出,并带回,再对top进行--操作
        return true;
    }
}

2.4.读栈顶元素

仅读取的话,不需要对top指针进行修改

//读栈顶元素
bool getTop(sqStack S, elemType &e){
    if(S.top == -1) return false;    //栈空,返回false
    else{
        e = S.data[S.top];    //读栈顶元素
        return true;
    }
}

2.5.共享栈

存元素时,top1指针往下递减,top0指针往上递增

栈满条件:top0 +1 == top1

#define maxSize 10
typedef struct{
    elemType data[maxSize];
    int top0;
    int top1;
}shStack;
void initStack{
    S.top0 = -1;    //初始化栈顶指针
    S.top1 = maxSize;
}

 

3.王道课后题

bool isLegal(string A) {
	int stack = 0;
	for (int i = 0; A[i] != '\0'; i++) {
		if (A[i] == 'I') stack++;
		else stack--;
		if (stack < 0) return false;
	}
	return true;
}

//链表方法
bool isSymmetry(linkList L) {
	LNode* fast = L->next, * slow = L->next;
	while (fast->next && fast->next->next) {
		slow = slow->next;
		fast = fast->next->next;
	}
	//p指向后半链表的第一个节点
	LNode* p = slow->next, *temp, *s;
	//将表分为前半链表和后半链表
	slow->next = NULL;
	//将s指向后半链表的第一个节点,p指向后半链表的最后一个节点
	s = p;
	while (p->next) p = p->next;
	//通过s和p将后半链表逆置
	while (s != p) {
		temp = s->next;
		s->next = p->next;
		p->next = s;
		s = temp;
	}
	//将s指向前半链表的第一个节点
	s = L->next;
	//依次对比前半链表和逆置后的后半链表
	while (p && s) {
		if (p->data != s->data) break;
		p = p->next;
		s = s->next;
	}
	//如果p在指向NULL之前就跳出循环,则不对称,返回false
	if (p) return false;
	else return true;
}
//栈
bool isSymmetry(linkList L, int n) {
	//创建数组作为栈,并初始化为0
	int* arr = (int*)malloc(sizeof(int) * (n / 2));
	memset(arr, 0, sizeof(char) * (n / 2));
	LNode* p = L->next;
	int i;
	//遍历前半链表,并将其数据压入栈中
	for (i = 0; i < n / 2; i++) {
		arr[i] = p->data;
		p = p->next;
	}
	//i退一格,使其指向栈顶元素
	i--;
	//如果是奇数个,当前p指向的是最中间节点
	//需要往后一个节点才是下半个链表的第一个节点
	if (n % 2) p = p->next;
	//依次判断下半链表元素是否与数组内元素相等
	while (p && p->data == arr[i]) {
		i--;
		p = p->next;
	}
	//判断是否提前跳出循环
	if (p) return false;
	else return true;
}

#define maxSize 10
typedef struct {
	elemType data[maxSize];
	int s1, s2;
}sqStack;
sqStack S;
//入栈
bool push(int i, sqStack S, elemType e) {
	//插入的栈号不对
	if (i < 1 || i > 2) return false;
	//栈满
	if (S.s1 + 1 == S.s2) return false;
	入栈
	if (i == 1) S.data[++S.s1] = e return true;;
	else S.data[--S.s2] = e return true;;
}
//出栈
bool pop(int i, sqStack S, elemType e) {
	//出栈的栈号不对
	if (i < 1 || i > 2) return false;
	//栈空
	if (i == 1 && S.s1 == -1) return false;
	else if (i == 2 && S.s2 == maxSize) return false;
	//出栈
	if (i == 1) e = S.data[S.s1--] return true;
	else e = S.data[S.s2++] return true;
}
举报

相关推荐

0 条评论