数据结构与算法分析——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
#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));
}
}