用一个数组实现三个栈

数据结构与算法分析——c语言描述 练习3.23 答案


这道题还是挺有意思的。第三个栈从中间开始,假如有冲突的时候还剩空位时候移动第三个栈到栈1和栈2顶端的中心。

要注意的是如何判断整个是否满了,以及每个栈是否能再继续进栈。第三个栈有些特殊。

编程很多时候并不能一步到位,需要不断debug,然后不停更改。当然一开始的思路方向是很重要的。


stack.h

typedef int ElementType;
#ifndef _stack_h
#define _stack_h

struct StackRecord;
typedef struct StackRecord *Stack;

int IsEmpty1(Stack s);
int IsEmpty2(Stack s);
int IsEmpty3(Stack s);
int IsFull(Stack s);
Stack CreateStack(int MaxElements);
void DisposeStack(Stack s);
void MakeEmpty1(Stack s);
void MakeEmpty2(Stack s);
void MakeEmpty3(Stack s);
void Push1(ElementType X, Stack s);
void Push2(ElementType X, Stack s);
void Push3(ElementType X, Stack s);
ElementType Top1(Stack s);
ElementType Top2(Stack s);
ElementType Top3(Stack s);
void Pop1(Stack s);
void Pop2(Stack s);
void Pop3(Stack s);
ElementType TopAndPop1(Stack s);
ElementType TopAndPop2(Stack s);
ElementType TopAndPop3(Stack s);
//void debug(Stack s);
//void debug2(Stack s);
#endif



stack.c
#include"stack.h"
#include<stdlib.h>
#include"fatal.h"

#define EmptyTOS1 (-1)
#define MinStackSize (5)

struct StackRecord {
	int Capacity;
	int TopOfStack1;
	int TopOfStack2;
	int BottemOfStack3;//第一个栈在左边,二在右边,三在中间向右边增长
	int TopOfStack3;
	ElementType *Array;
};

static int IsCanPush1(Stack s) {
	if (IsEmpty3(s))
	{
		return s->TopOfStack1 + 1 < s->TopOfStack2;
	}
	else//stack3不为空
		return s->TopOfStack1 + 1 < s->BottemOfStack3;
}

static int IsCanPush3(Stack s) {

	return (s->TopOfStack1<s->BottemOfStack3) && s->TopOfStack3 + 1 < s->TopOfStack2;
}

static int IsCanPush2(Stack s) {
	if (IsEmpty3(s))
	{
		return s->TopOfStack1 + 1 < s->TopOfStack2;
	}
	else
		return s->TopOfStack3 + 1 < s->TopOfStack2;
}

static void move(Stack s) {
	int centerOfStack3 = (s->BottemOfStack3 + s->TopOfStack3 + 1) / 2;//加1是为了当为0.5时进1
	int centerBeteweenStack1With2 = (s->TopOfStack1 + s->TopOfStack2) / 2;
	int offset = centerBeteweenStack1With2 - centerOfStack3;
	if (offset < 0)
		for (int i = s->BottemOfStack3; i <= s->TopOfStack3; i++)
			s->Array[i + offset] = s->Array[i];
	else if (offset>0)
		for (int i = s->TopOfStack3; i >= s->BottemOfStack3; i--)
			s->Array[i + offset] = s->Array[i];

	s->BottemOfStack3 += offset;
	s->TopOfStack3 += offset;
}

int IsEmpty1(Stack s) {
	return s->TopOfStack1 == EmptyTOS1;
}

int IsEmpty2(Stack s) {
	return s->TopOfStack2 == s->Capacity;
}

int IsEmpty3(Stack s) {
	return s->TopOfStack3 < s->BottemOfStack3;
}

int IsFull(Stack s) {
	return !IsCanPush1(s) && !IsCanPush3(s) && !IsCanPush2(s);
}

Stack CreateStack(int MaxElements) {
	Stack s;
	if (MaxElements < MinStackSize)
		Error("Stack size is too small");
	s = malloc(sizeof(struct StackRecord));
	if (s == NULL)
		Error("out of space");
	else {
		s->Array = malloc(sizeof(ElementType)*MaxElements);
		if (s->Array == NULL)
			Error("out of space");
		else {
			s->Capacity = MaxElements;
			MakeEmpty1(s);
			MakeEmpty2(s);
			MakeEmpty3(s);
		}
	}
	return s;
}

void DisposeStack(Stack s) {
	if (s != NULL) {
		free(s->Array);
		free(s);
	}
}

void MakeEmpty1(Stack s) {
	s->TopOfStack1 = -1;
}

void MakeEmpty2(Stack s) {
	s->TopOfStack2 = s->Capacity;
}

void MakeEmpty3(Stack s) {
	s->BottemOfStack3 = s->Capacity / 2;
	s->TopOfStack3 = s->BottemOfStack3 - 1;
}

void Push1(ElementType X, Stack s) {
	if (IsFull(s))
	{
		Error("out of space");
	}

	if (IsCanPush1(s))
	{
		s->Array[++s->TopOfStack1] = X;
		return;
	}
	else {
		move(s);
		s->Array[++s->TopOfStack1] = X;
	}

}

void Push2(ElementType X, Stack s) {
	if (IsFull(s))
		Error("out of space");
	if (IsCanPush2(s))
	{
		s->Array[--s->TopOfStack2] = X;
		return;
	}
	else {
		printf("sdfsf232\n");
		move(s);
		s->Array[--s->TopOfStack2] = X;
	}
}

void Push3(ElementType X, Stack s) {
	if (IsFull(s))
		Error("out of space");
	if (IsCanPush3(s))
	{
		s->Array[++s->TopOfStack3] = X;
		return;
	}
	else {
		move(s);
		s->Array[++s->TopOfStack3] = X;
	}
}


ElementType Top1(Stack s) {
	if (IsEmpty1(s))
		Error("Empty stack");
	return s->Array[s->TopOfStack1];
}

ElementType Top2(Stack s) {
	if (IsEmpty2(s))
		Error("Empty stack");
	return s->Array[s->TopOfStack2];
}

ElementType Top3(Stack s) {
	if (IsEmpty3(s))
		Error("Empty stack");
	return s->Array[s->TopOfStack3];
}

void Pop1(Stack s) {
	if (IsEmpty1(s))
		Error("Empty stack");
	s->TopOfStack1--;
}

void Pop2(Stack s) {
	if (IsEmpty2(s))
		Error("Empty stack");
	s->TopOfStack2++;
}

void Pop3(Stack s) {
	if (IsEmpty3(s))
		Error("Empty stack");
	s->TopOfStack3--;
}

ElementType TopAndPop1(Stack s) {
	if (IsEmpty1(s))
		Error("empty stack");
	return s->Array[s->TopOfStack1--];
}

ElementType TopAndPop2(Stack s) {
	if (IsEmpty2(s))
		Error("empty stack");
	return s->Array[s->TopOfStack2++];
}

ElementType TopAndPop3(Stack s) {
	if (IsEmpty3(s))
		Error("empty stack");
	return s->Array[s->TopOfStack3--];
}

/*
void debug(Stack s) {
	for (int i = 0; i < s->Capacity; i++)
		printf("%d ", s->Array[i]);
	printf("\n");
}

void debug2(Stack s) {
	printf("%d %d %d %d \n", s->TopOfStack1, s->BottemOfStack3, s->TopOfStack3, s->TopOfStack2);
}
*/


main.c

#include"stack.h"
#include<stdio.h>
int main() {
	Stack s = CreateStack(9);
	for (int i = 0; i < 9; i++) {
		Push3(i, s);
		//debug(s);
	}
	for (int i = 0; i < 9; i++) {
		printf("%d",TopAndPop3(s));
	}
}


你可能感兴趣的:(用一个数组实现三个栈)