赞
踩
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
顺序栈是栈的顺序实现。顺序栈是指利用顺序存储结构实现的栈。采用地址连续的存储空间(数组)依次存储栈中的数据元素,由于入栈和出栈运算都是在栈顶进行,而栈底位置是固定不变的,可以将栈底位置设置在数组空间的起始处;栈顶位置是随入栈和出栈操作而变化的,故需用一个整型变量top来记录当前栈顶元素在数组中的位置。
在顺序栈的操作中可能存在两种溢出。
上溢:
下溢:
//定义栈处理的数据类型 typedef int StackElemType; /*定义栈的最大长度*/ #define STACK_MAX_SIZE 100 /*顺序栈的结构*/ typedef struct stack { //栈顶位置当top=-1表示空栈,top=stack_size-1表示栈满 int top; StackElemType date[STACK_MAX_SIZE]; }Stack,*StackPtr; //定义状态 typedef enum Status { success, fail, overflow, /*上溢*/ underflow/*下溢*/ }Status;
/************************************** *函数名称:Statck_Init(StackPtr s) *描 述: * 初始化一个栈 *参 数: * StackPtr s 传入需要初始化的栈 *返回值 : * success 成功 * fail 失败 ***************************************/ Status Stack_Init(StackPtr s) { Status outcome = fail; StackPtr p = NULL; p = (StackPtr)malloc(STACK_MAX_SIZE*sizeof(StackElemType)); if(p == NULL) { return outcome;/*空间未申请成功*/ } s->top = -1; outcome = success; return outcome; }
/*************************************************** *函数名称:Stack_Push(StackPtr s,StackElemType elem) *描 述: * 顺序栈入栈操作的实现 *参 数: * StackPtr s 传入栈 * StackElemType elem 需要压栈的数据 *返回值 : * success 成功 * overflow 栈上溢出 ****************************************************/ Status Stack_Push(StackPtr s, StackElemType elem) { Status outcome = success; if(s->top == STACK_MAX_SIZE -1) { outcome = overflow;/*栈满,上溢*/ } s -> top++; s -> date[s->top] = elem; return outcome; }
/*************************************************** *函数名称:Stack_Pop(StackPtr s,StackElemType *elem) *描 述: * 顺序栈出栈操作的实现 *参 数: * StackPtr s 传入栈 * StackElemType *elem 出栈的数据赋值给*elem *返回值: * success 成功 * underflow 栈下溢出 ****************************************************/ Status Stack_Pop(StackPtr s,StackElemType *elem) { Status outcome = success; if(s -> top == -1) { outcome = underflow;/*栈下溢*/ } else { *elem = s->date[s->top]; s -> top--; } return outcome; }
/*************************************************** *函数名称:Stack_Clear(StackPtr s) *描 述: * 清除栈 *参 数: * StackPtr s 传入被清空的栈 *返回值: * 无 ****************************************************/ void Stack_Clear(StackPtr s) { if(s) { s -> top = -1; } }
/***************************************************
*函数名称:Stack_Empty(StackPtr s)
*描 述:
* 判断栈是否为空
*参 数:
* StackPtr s 传入栈
*返回值:
* 1 空栈
* 0 不为空
****************************************************/
bool Stack_Empty(StackPtr s)
{
return (s -> top == -1);
}
链栈是一种数据存储结构,可以通过单链表的方式来实现,使用链栈的优点在于它能够克服用数组实现的顺序栈空间利用率不高的特点,但是需要为每个栈元素分配额外的指针空间用来存放指针域。
#define bool int /*链栈的大小*/ #define STACK_MAX_SIZE 20 /*定义待处理的数据类型*/ typedef int ElemType; /*链栈结点的结构*/ typedef struct Stacknode { ElemType data; struct Stacknode *next; }Stacknode,*PtrStacknode; /*栈的类型*/ typedef struct{ PtrStacknode top; int count; }LinkStack; /*定义状态*/ typedef enum Statuc{ success, fail, error, full, empty }Status;
/************************************** *函数名称:Stack_Init(LinkStack *s) *描 述: * 初始化一个链栈 *参 数: * LinkStack *s 传入需要初始化的栈 *返回值 : * success 成功 * fail 失败 * top top-1 * ------- ------- ------- ------- | | | | | | ~~~ | | | | | | * ------- ------- ------- ------- * \_________________ ___________________/ * \/ * 栈顶 count 栈尾 *注 意:栈顶为链表得第一个元素 ***************************************/ Status Stack_Init(LinkStack *s) { Status outcome = fail; s ->top = (PtrStacknode)malloc(sizeof(Stacknode)); if(!s->top) { return outcome;/*空间申请失败*/ } else { s ->top = NULL; s ->count = 0; outcome = success; } return outcome; }
/************************************** *函数名称:Stack_Push(LinkStack *Stack, ElemType *elem) *描 述: * 压栈操作 *参 数: * LinkStack *Stack 传入的栈 * ElemType *elem 待压入的数据 *返回值 : * success 成功 * fail 失败 ***************************************/ Status Stack_Push(LinkStack *Stack, ElemType *elem) { Status outcome = success; PtrStacknode s = (PtrStacknode)malloc(sizeof(Stacknode)); if(s != NULL) { s ->data = *elem; s ->next = Stack ->top; Stack ->top = s; Stack ->count++; } else { outcome = fail;/*压栈操作失败*/ } return outcome; }
/************************************** *函数名称:Stack_Pop(LinkStack *Stack,ElemType *elem) *描 述: * 出栈操作 *参 数: * LinkStack *Stack 传入的栈 * ElemType *elem 出栈的数据保存到*elem *返回值 : * success 成功 * empty 空栈无法弹出 ***************************************/ Status Stack_Pop(LinkStack *Stack,ElemType *elem) { Status outcome = success; if(Stack ->count != 0) { *elem = Stack ->top ->data; Stack ->top = Stack ->top ->next; Stack ->count--; } else { outcome = empty;/*空栈无法弹出*/ } return outcome; }
/**************************************
*函数名称:Stack_Empty(LinkStack *s)
*描 述:
* 判断栈是否为空
*参 数:
* LinkStack *s 传入的栈
*返回值 :
* 1 空栈
* 0 非空
***************************************/
bool Stack_Empty(LinkStack *s)
{
return (s ->count == 0);
}
用一个数组来存储两个栈,数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组长度的n-1处。两个栈如果增加元素,就是两端点向中间延伸
#define bool int /*存储空间分配*/ #define STACK_MAX_SIZE 20 #define STACK_ONE 1 #define STACK_TWO 2 /*栈中保存的数据类型*/ typedef int ElemType; /*两栈共享空间结构*/ typedef struct stack{ ElemType date[STACK_MAX_SIZE]; int stack_top1;/*栈1栈顶指针*/ int stack_top2;/*栈2栈顶指针*/ }DoubleStack,*PtrDoubleStack; /*定义函数的返回状态*/ typedef enum Status{ success, fail, error, full, empty }Status;
/************************************** *函数名称:Stack_Init(PtrDoubleStack s) *描 述: * 初始化一个共享空间的栈 *参 数: * PtrDoubleStack s 传入需要初始化的栈 *返回值 : * success 成功 * fail 失败 ***************************************/ Status Stack_Init(PtrDoubleStack s) { Status outcome = fail; s ->stack_top1 = -1; s -> stack_top2 = STACK_MAX_SIZE; outcome = success; return outcome; }
/*************************************************** *函数名称:Stack_Push(PtrDoubleStack s,ElemType e,int StackNumber) *描 述: * 压栈操作 *参 数: * PtrDoubleStack s 传入栈 * ElemType e 带压入的数据 * int StackNumber 压入哪个栈 *返回值: * fail 失败 * full 满栈 * success 成功 * error 错误 *注 意: * top1 top2 * -------------- -------------- * | | | | | | | | | | * -------------- -------------- * 0 1 2 3 4 5 6 7 ****************************************************/ Status Stack_Push(PtrDoubleStack s, ElemType *e, int StackNumber) { Status outcome = fail; if(s -> stack_top1 + 1 == s -> stack_top2) { outcome = full;/*栈已满,不能再压入新的数据*/ } else { if(StackNumber == STACK_ONE)/*压入栈1*/ { s -> date[++s -> stack_top1] = *e; outcome = success; } else if(StackNumber == STACK_TWO)/*压入栈2*/ { s -> date[--s -> stack_top2] = *e; outcome = success; } else { outcome = error;/*出入的StackNumber错误*/ } } return outcome; }
/************************************** *函数名称:Stack_Pop(PtrDoubleStack s, ElemType *elem, int StackNumber) *描 述: * 出栈操作 *参 数: * PtrDoubleStack s 传入的栈 * ElemType *elem 出栈的数据赋值给*elem * int StackNumber 确定出栈的栈 *返回值 : * success 成功 * fail 失败 * error 错误 * empty 空栈 ***************************************/ Status Stack_Pop(PtrDoubleStack s, ElemType *elem, int StackNumber) { Status outcome = error; if(s -> stack_top1 == -1 || s -> stack_top2 == STACK_MAX_SIZE) { outcome = empty;/*空栈无法继续弹出数据*/ } else { if(StackNumber == STACK_ONE) { *elem = s -> date[s -> stack_top1--]; outcome = success; } else if(StackNumber == STACK_TWO) { *elem = s -> date[s -> stack_top2++]; outcome = success; } else { outcome = error;/*出入的StackNumber错误*/ } } return outcome; }
/************************************** *函数名称:Stack_Clear(PtrDoubleStack s) *描 述: * 清空栈 *参 数: * PtrDoubleStack s 传入的栈 *返回值 : * fail 失败 * success 成功 ***************************************/ Status Stack_Clear(PtrDoubleStack s) { Status outcome = fail; if(s) { s ->stack_top1 = -1; s ->stack_top2 = STACK_MAX_SIZE; if(s ->stack_top1 == -1 && s ->stack_top2 == STACK_MAX_SIZE) { outcome = success; } else { outcome = fail; } } return outcome; }
/**************************************
*函数名称:Stack_Length(PtrDoubleStack s)
*描 述:
* 共享栈的数据个数即栈的长度
*参 数:
* PtrDoubleStack s 传入的栈
*返回值 :
* 栈的长度
***************************************/
int Stack_Length(PtrDoubleStack s)
{
return ((s -> stack_top1+1) + (STACK_MAX_SIZE - s->stack_top2));
}
/**************************************
*函数名称:Stack_Empty(PtrDoubleStack s)
*描 述:
* 判断栈是否为空
*参 数:
* PtrDoubleStack s 传入的栈
*返回值 :
* 1 空栈
* 0 非空
***************************************/
bool Stack_Empty(PtrDoubleStack s)
{
return (s ->stack_top1 == -1 && s ->stack_top2 == STACK_MAX_SIZE);
}
首先需要初始化栈以及压栈处理
InitStack(&s);
printf("请输入二进制数,输入字母q结束:");
scanf("%c",&c);
while (c != 'q')
{
PushStack(&s,c);
scanf("%c",&c);
}
getchar();/*由于一般是\n结尾,需要将\n从输入的数据中剔除*/
len = LengthStack(&s);
这里c-48是由于计算机保存数据为ASICII形式
for(i = 0; i< len; i++)
{
PopStack(&s,c);
sum = sum+(c-48)*pow(2,i);
}
/*2进制转8进制方法*/ for(i =0; i< len; i++) { for(j =0;j < 3; j++) { PopStack(&s,c); sum = sum +(c-48)*pow(2,j); } if(s.top == s.base) { break; } PushStack(&s2,sum+48); sum = 0; } print("转换后的8进制数为:"); while(s2.top != s2.base) { PopStack(&s2,c); printf("%c",c); }
/*2进制转16进制方法*/ for(i =0; i< len;i++) { for(j =0; j<4;j++) { PopStack(&s,c); sum = sum+(c-48)*pow(2,j); } if(s.base == s.top) { break; } switch (sum) { case 10: sum = 'A'; break; case 11: sum = 'B'; break; case 12: sum = 'C'; break; case 13: sum = 'D'; break; case 14: sum = 'E'; break; case 15: sum = 'F'; break; default: sum += 48; break; } PushStack(&s2,sum); sum = 0; printf("转换后的16进制数为:0X"); while (s2.base != s2.top) { PopStack(&s2,c); printf("%c",c); } printf("H\n"); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。