2018/3/12
数据结构
1.栈
1.堆栈是一种特殊的线性表,遵循先进后出的原则,可以看做手枪的弹夹一样,先进的子弹反而最后出
2.栈的主要类型:顺序栈(操作数组操作),链栈(操作指针)
3.栈由于是一种特殊的线性表,因此可以仿造线性表的操作方式,但是在插入和删除时要小心,在表的一侧进行操作
4.栈的主要操作方式
4-1:新建栈(init_stack)
4-2:进栈(push)
4-3:出栈(pop)
4-4:判断是否为空(isNotEmpty)
4-5:取栈顶元素(stackTop)
4-6:栈的删除(destory)
2.顺序栈的操作技巧
//头文件
//顺序栈的简单操作
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
struct sqStack
{
int data[MAXSIZE];//定义
int top;
};
//创建栈
int initStack(struct sqStack*S)
{
S->data[0] = 0;
S->top = 0;
printf("初始化成功\n");
return 1;
}
//入栈
int pushStack(struct sqStack *S, int e)
{
if (S->top >= MAXSIZE)
{
printf("栈已经满了\n");
return 0;
}
else
{
S->data[S->top] = e;
S->top++;
return 1;
}
}
//出栈
int popStack(struct sqStack *S, int *e)
{
if (S->top <= 0)
{
printf("该栈已空\n");
return 0;
}
else
{
S->top--;
*e = S->data[S->top];
return 1;
}
}
//取栈顶元素
int stackTop(struct sqStack *S, int *n)
{
if (S->top <= 0)
{
printf("该栈已空\n");
return 0;
}
else
{
*n = S->data[S->top - 1];
return 1;
}
}
int stackNotEmpty(sqStack S)
{
if (S.top <= 0)
{
return 0;
}
else
return 1;
}
//源文件
#include"sqStack.h"
#include<stdio.h>
#include<stdlib.h>
void main()
{
sqStack S;
int n, e;
initStack(&S);
pushStack(&S, 10);
pushStack(&S, 9);
pushStack(&S, 8);
pushStack(&S, 7);
pushStack(&S, 6);
pushStack(&S, 5);
pushStack(&S, 4);
if (stackTop(&S, &n) == 0)
{
printf("错误\n");
}
else
printf("栈顶元素为%2d\n", n);
printf("\n依次出栈的情况如下\n:");
while (stackNotEmpty(S))
{
popStack(&S, &e);
printf("%3d", e);
}
system("pause");
}
链栈的使用
//链栈的简单使用
/*头文件*/
//链栈和普通单链表的区别无非是插入和删除在栈顶
#include<stdio.h>
#include<stdlib.h>
struct Stack
{
int data;
struct Stack *next;
};
struct Stack * init_Stack(struct Stack *);//初始化
struct Stack * pushStack(struct Stack *head,int x);//入栈
void disp_stack(struct Stack *);//显示链栈
int count_stack(struct Stack *);//计算链栈的数据个数
int popStack(struct Stack *, int *d);//出栈
int stackTop(struct Stack *, int*);//取栈顶元素
void destoryStack(struct Stack*);//破坏栈
//初始化链栈
struct Stack * init_Stack(struct Stack *head)
{
struct Stack* p = (struct Stack*)malloc(sizeof(struct Stack));//分配空间
p->data = 0;
p->next = NULL;
printf("\n初始化成功\n");
return p;
}
//显示链栈
void disp_stack(struct Stack *head)
{
struct Stack *p;
printf("链栈:");
if (head == NULL)
printf("(空)\n");
else
{
p = head;
while (p!= NULL)
{
printf("%4d\n", p->data);
p = p->next;
}
}
printf("\n");
}
//计算链栈中的元素
int count_stack(struct Stack *head)
{
struct Stack *p;
int k = 0;
p = head;
while (p != NULL)
{
k++;
p = p->next;
}
return k;
}
//入栈
struct Stack * pushStack(struct Stack *head, int x)
{
struct Stack *p;
p = (struct Stack *)malloc(sizeof(struct Stack));
/*入栈操作,只在链表的一端操作*/
p->data = x;
p->next = head->next;
head->next = p;
return head;
}
//出栈
int popStack(struct Stack *head, int *d)//出栈,用d将参数带回
{
struct Stack *p = head->next;
if (p == NULL)
{
printf("\n链栈已空,出现错误\n");
return 0;
}
/*删除操作*/
head->next = p->next;
*d = p->data;
free(p);
printf("%5d", *d);
}
/*取栈顶元素*/
int stackTop(struct Stack *head, int *num)
{
struct Stack *p = head->next;
if (p == NULL)
{
printf("链栈已空,取数失败");
return 0;
}
*num = p->data;
return 1;
}
//破坏栈
void destoryStack(struct Stack*head)
{
struct Stack *p, *q;
p = head;
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
printf("删除成功");
}
//源文件
//链栈的使用
/*链栈和线性表的区别就是在插入和删除的时候要在同一侧进行操作*/
#include<stdio.h>
#include<stdlib.h>
#include"linkStackPractice.h"
void main()
{
struct Stack *head;
int n, top, num, length,i;
head = NULL;
head = init_Stack(head);//初始化
/*入栈*/
head = pushStack(head,35);
head = pushStack(head,45);
head = pushStack(head,55);
head = pushStack(head,65);
head = pushStack(head,75);
head = pushStack(head,85);
disp_stack(head);
stackTop(head, &n);
length = count_stack(head);
printf("\n出栈的元素为:\n");
for (i = 0; i < length; i++)
{
popStack(head, &num);
}
destoryStack(head);
system("pause");
}
注意事项:由于C语言和Pascal语言的标准不一样,使用时注意从0开始还是从1开始