来源:互联网 发布:matlab可以用c语言吗 编辑:程序博客网 时间:2024/06/06 06:53

1.顺序栈

头文件

#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h> /* exit() *//* 函数结果状态代码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef char ElemType;/* algo3-5.c 利用栈求解迷宫问题(只输出一个解,算法3.3) */typedef struct /* 迷宫坐标位置类型 */{int x; /* 行值 */int y; /* 列值 */}PosType;//typedef struct /* 栈的元素类型 *///{//int ord; /* 通道块在路径上的"序号" *///PosType seat; /* 通道块在迷宫中的"坐标位置" *///int di; /* 从此通道块走向下一通道块的"方向"(0~3表示东~北) *///}ElemType;#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */#define STACKINCREMENT 2 /* 存储空间分配增量 */typedef struct stack{ElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */ElemType *top; /* 栈顶指针 */int stacksize; /* 当前已分配的存储空间,以元素为单位 */}stack; /* 顺序栈 */Status create(stack *S);Status destroy(stack *S);Status clear(stack *S);Status empty(stack S);int size(stack S);ElemType top(stack S);Status push(stack *S, ElemType e);Status pop(stack *S);Status traverse(stack S, Status(*visit)(ElemType));
实现文件

#include "stack.h"Status create(stack *S){ /* 构造一个空栈S */(*S).base = (ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));if (!(*S).base)exit(OVERFLOW); /* 存储分配失败 */(*S).top = (*S).base;(*S).stacksize = STACK_INIT_SIZE;return OK;}Status destroy(stack *S){ /* 销毁栈S,S不再存在 */free((*S).base);(*S).base = NULL;(*S).top = NULL;(*S).stacksize = 0;return OK;}Status clear(stack *S){ /* 把S置为空栈 */(*S).top = (*S).base;return OK;}Status empty(stack S){ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */if (S.top == S.base)return TRUE;elsereturn FALSE;}int size(stack S){ /* 返回S的元素个数,即栈的长度 */return S.top - S.base;}ElemType top(stack S){ /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */if (S.top > S.base){return *(S.top - 1);}else{puts("try to get a elment from a empty stack");exit(0);}}Status push(stack *S, ElemType e){ /* 插入元素e为新的栈顶元素 */if ((*S).top - (*S).base >= (*S).stacksize) /* 栈满,追加存储空间 */{(*S).base = (ElemType *)realloc((*S).base, ((*S).stacksize + STACKINCREMENT)*sizeof(ElemType));if (!(*S).base)exit(OVERFLOW); /* 存储分配失败 */(*S).top = (*S).base + (*S).stacksize;(*S).stacksize += STACKINCREMENT;}*((*S).top)++ = e;return OK;}Status pop(stack *S){ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */if ((*S).top == (*S).base)return ERROR;--(*S).top;return OK;}Status traverse(stack S, Status(*visit)(ElemType)){ /* 从栈底到栈顶依次对栈中每个元素调用函数visit()。 *//* 一旦visit()失败,则操作失败 */while (S.top>S.base)visit(*S.base++);printf("\n");return OK;}

测试文件一

#include "stack.h"Status visit(ElemType c){printf("%d ", c);return OK;}void main(){int j;stack s;ElemType e;  if (create(&s) == OK)for (j = 1; j <= 12; j++)push(&s, j);printf("栈中元素依次为:");traverse(s, visit);pop(&s);printf("弹出的栈顶元素\n");printf("栈空否:%d(1:空 0:否)\n", empty(s));top(s, &e);printf("栈顶元素 e=%d 栈的长度为%d\n", e, size(s));clear(&s);printf("清空栈后,栈空否:%d(1:空 0:否)\n", empty(s));destroy(&s);printf("销毁栈后,s.top=%u s.base=%u s.stacksize=%d\n", s.top, s.base, s.stacksize);}

测试文件二

#include "stack.h"void conversion() /* 算法3.1 */{ /* 对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数 */stack s;unsigned n; /* 非负整数 */ElemType e;create(&s); /* 初始化栈 */printf("n(>=0)=");scanf("%u", &n); /* 输入非负十进制整数n */while (n) /* 当n不等于0 */{push(&s, n % 8); /* 入栈n除以8的余数(8进制的低位) */n = n / 8;}while (!empty(s)) /* 当栈不空 */{e = top(s); /* 弹出栈顶元素且赋值给e */pop(&s);printf("%d", e); /* 输出e */}printf("\n");}void main(){conversion();}

测试文件三

#include "stack.h"void conversion(){ /* 对于输入的任意一个非负10进制整数,打印输出与其等值的16进制数 */stack s;unsigned n; /* 非负整数 */ElemType e;create(&s); /* 初始化栈 */printf("n(>=0)=");scanf("%u", &n); /* 输入非负十进制整数n */while (n) /* 当n不等于0 */{push(&s, n % 16); /* 入栈n除以16的余数(16进制的低位) */n = n / 16;}while (!empty(s)) /* 当栈不空 */{e = top(s); /* 弹出栈顶元素且赋值给e */pop(&s);if (e <= 9)printf("%d", e);elseprintf("%c", e + 55);}printf("\n");}void main(){conversion();}

测试文件四

#include "stack.h"void check(){ /* 对于输入的任意一个字符串,检验括号是否配对 */stack s;ElemType ch[80], *p, e;if (create(&s)) /* 初始化栈成功 */{printf("请输入表达式\n");gets(ch);p = ch;while (*p) /* 没到串尾 */switch (*p){case '(':case '[':push(&s, *p++);break; /* 左括号入栈,且p++ */case ')':case ']':if (!empty(s)) /* 栈不空 */{ e = top(s); /* 弹出栈顶元素 */ pop(&s); if (*p == ')'&&e != '(' || *p == ']'&&e != '[') /* 弹出的栈顶元素与*p不配对 */ { printf("左右括号不配对\n"); exit(ERROR); } else { p++; break; /* 跳出switch语句 */ }} else /* 栈空 */ { printf("缺乏左括号\n"); exit(ERROR); }default: p++; /* 其它字符不处理,指针向后移 */}if (empty(s)) /* 字符串结束时栈空 */printf("括号匹配\n");elseprintf("缺乏右括号\n");}}void main(){check();}

测试文件五

#include "stack.h"FILE *fp;Status copy(ElemType c){ /* 将字符c送至fp所指的文件中 */fputc(c, fp);return OK;}void LineEdit(){ /* 利用字符栈s,从终端接收一行并送至调用过程的数据区。算法3.2 */stack s;char ch, c;create(&s);printf("请输入一个文本文件,^Z结束输入:\n");ch = getchar();while (ch != EOF){ /* EOF为^Z键,全文结束符 */while (ch != EOF&&ch != '\n'){switch (ch){case '#':c = top(s);  pop(&s);break; /* 仅当栈非空时退栈 */case '@':clear(&s);break; /* 重置s为空栈 */default:push(&s, ch); /* 有效字符进栈 */}ch = getchar(); /* 从终端接收下一个字符 */}traverse(s, copy); /* 将从栈底到栈顶的栈内字符传送至文件 */clear(&s); /* 重置s为空栈 */fputc('\n', fp);if (ch != EOF)ch = getchar();}destroy(&s);}void main(){fp = fopen("ED.DAT", "w"); /* 在当前目录下建立ED.DAT文件,用于写数据, */if (fp)                  /* 如已有同名文件则先删除原文件 */{LineEdit();fclose(fp); /* 关闭fp所指的文件 */}elseprintf("建立文件失败!\n");}

测试文件六

#include "stack.h"#define MAXLENGTH 25 /* 设迷宫的最大行列为25 */typedef int MazeType[MAXLENGTH][MAXLENGTH]; /* 迷宫数组[行][列] *//* 全局变量 */MazeType m; /* 迷宫数组 */int curstep = 1; /* 当前足迹,初值为1 *//* 定义墙元素值为0,可通过路径为1,不能通过路径为-1,通过路径为足迹 */Status Pass(PosType b){ /* 当迷宫m的b点的序号为1(可通过路径),return OK; 否则,return ERROR。 */if (m[b.x][b.y] == 1)return OK;elsereturn ERROR;}void FootPrint(PosType a){ /* 使迷宫m的a点的序号变为足迹(curstep) */m[a.x][a.y] = curstep;}PosType NextPos(PosType c, int di){ /* 根据当前位置及移动方向,返回下一位置 */PosType direc[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; /* {行增量,列增量} *//* 移动方向,依次为东南西北 */c.x += direc[di].x;c.y += direc[di].y;return c;}void MarkPrint(PosType b){ /* 使迷宫m的b点的序号变为-1(不能通过的路径) */m[b.x][b.y] = -1;}Status MazePath(PosType start, PosType end) /* 算法3.3 */{ /* 若迷宫maze中存在从入口start到出口end的通道,则求得一条 *//* 存放在栈中(从栈底到栈顶),并返回TRUE;否则返回FALSE */stack S;PosType curpos;ElemType e;create(&S);curpos = start;do{if (Pass(curpos)){ /* 当前位置可以通过,即是未曾走到过的通道块 */FootPrint(curpos); /* 留下足迹 */e.ord = curstep;e.seat.x = curpos.x;e.seat.y = curpos.y;e.di = 0;push(&S, e); /* 入栈当前位置及状态 */curstep++; /* 足迹加1 */if (curpos.x == end.x&&curpos.y == end.y) /* 到达终点(出口) */return TRUE;curpos = NextPos(curpos, e.di);}else{ /* 当前位置不能通过 */if (!empty(S)){e = top(S); /* 退栈到前一位置 */pop(&S);curstep--;while (e.di == 3 && !empty(S)) /* 前一位置处于最后一个方向(北) */{MarkPrint(e.seat); /* 留下不能通过的标记(-1) */e = top(S); /* 退栈到前一位置 */pop(&S);curstep--;}if (e.di<3) /* 没到最后一个方向(北) */{e.di++; /* 换下一个方向探索 */push(&S, e);curstep++;curpos = NextPos(e.seat, e.di); /* 设定当前位置是该新方向上的相邻块 */}}}} while (!empty(S));return FALSE;}void Print(int x, int y){ /* 输出迷宫的解 */int i, j;for (i = 0; i<x; i++){for (j = 0; j<y; j++)printf("%3d", m[i][j]);printf("\n");}}void main(){PosType begin, end;int i, j, x, y, x1, y1;printf("请输入迷宫的行数,列数(包括外墙):");scanf("%d,%d", &x, &y);for (i = 0; i<x; i++) /* 定义周边值为0(同墙) */{m[0][i] = 0; /* 行周边 */m[x - 1][i] = 0;}for (j = 1; j<y - 1; j++){m[j][0] = 0; /* 列周边 */m[j][y - 1] = 0;}for (i = 1; i<x - 1; i++)for (j = 1; j<y - 1; j++)m[i][j] = 1; /* 定义通道初值为1 */printf("请输入迷宫内墙单元数:");scanf("%d", &j);printf("请依次输入迷宫内墙每个单元的行数,列数:\n");for (i = 1; i <= j; i++){scanf("%d,%d", &x1, &y1);m[x1][y1] = 0; /* 定义墙的值为0 */}printf("迷宫结构如下:\n");Print(x, y);printf("请输入起点的行数,列数:");scanf("%d,%d", &begin.x, &begin.y);printf("请输入终点的行数,列数:");scanf("%d,%d", &end.x, &end.y);if (MazePath(begin, end)) /* 求得一条通路 */{printf("此迷宫从入口到出口的一条路径如下:\n");Print(x, y); /* 输出此通路 */}elseprintf("此迷宫没有从入口到出口的路径\n");}

测试文件七
#include "stack.h"//目测不正确,需要修改ElemType Precede(ElemType t1, ElemType t2){ /* 根据教科书表3.1,判断两符号的优先关系 */ElemType f;switch (t2){case '+':case '-':if (t1 == '(' || t1 == '#')f = '<'; else f = '>';break;case '*':case '/':if (t1 == '*' || t1 == '/' || t1 == ')')f = '>'; else f = '<';break;case '(':if (t1 == ')'){ printf("ERROR1\n"); exit(ERROR);} else f = '<';break;case ')':switch (t1){case '(':f = '=';break;case '#':printf("ERROR2\n");exit(ERROR);default: f = '>';} break;case '#':switch (t1){case '#':f = '=';break;case '(':printf("ERROR3\n");exit(ERROR);default: f = '>';}}return f;}Status In(ElemType c){ /* 判断c是否为运算符 */switch (c){case'+':case'-':case'*':case'/':case'(':case')':case'#':return TRUE;default:return FALSE;}}ElemType Operate(ElemType a, ElemType theta, ElemType b){ElemType c;a = a - 48;b = b - 48;switch (theta){case'+':c = a + b + 48;break;case'-':c = a - b + 48;break;case'*':c = a*b + 48;break;case'/':c = a / b + 48;}return c;}ElemType EvaluateExpression() /* 算法3.4 */{ /* 算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈 */stack OPTR, OPND;ElemType a, b, c, x, theta;create(&OPTR);push(&OPTR, '#');create(&OPND);c = getchar();x = top(OPTR);while (c != '#' || x != '#'){if (In(c)) /* 是7种运算符之一 */switch (Precede(x, c)){case'<':push(&OPTR, c); /* 栈顶元素优先权低 */c = getchar();break;case'=':x = top(OPTR); pop(&OPTR); /* 脱括号并接收下一字符 */c = getchar();break;case'>':theta = top(OPTR); pop(&OPTR); /* 退栈并将运算结果入栈 */b = top(OPND);  pop(&OPND);a = top(OPND);  pop(&OPND);push(&OPND, Operate(a, theta, b));break;}else if (c >= '0'&&c <= '9') /* c是操作数 */{push(&OPND, c);c = getchar();}else /* c是非法字符 */{printf("ERROR4\n");exit(ERROR);}x = top(OPTR);}x = top(OPTR);return x;}void main(){printf("请输入算术表达式(中间值及最终结果要在0~9之间),并以#结束\n");printf("%c\n", EvaluateExpression());}
测试文件八

#include "stack.h"ElemType Precede(ElemType t1, ElemType t2) /* 同algo3-6.c */{ /* 根据教科书表3.1,判断两符号的优先关系 */ElemType f;switch (t2){case '+':case '-':if (t1 == '(' || t1 == '=')f = '<'; else f = '>';break;case '*':case '/':if (t1 == '*' || t1 == '/' || t1 == ')')f = '>'; else f = '<';break;case '(':if (t1 == ')'){ printf("ERROR1\n"); exit(ERROR);} else f = '<';break;case ')':switch (t1){case '(':f = '=';break;case '=':printf("ERROR2\n");exit(ERROR);default: f = '>';} break;case '=':switch (t1){case '=':f = '=';break;case '(':printf("ERROR2\n");exit(ERROR);default: f = '>';}}return f;}Status In(ElemType c) /* 几乎与algo3-6.c相同 */{ /* 判断c是否为运算符 */switch (c){case'+':case'-':case'*':case'/':case'(':case')':case'=':return TRUE; /* 此句不同于algo3-6.c */default:return FALSE;}}ElemType Operate(ElemType a, ElemType theta, ElemType b) /* 有改动 */{ElemType c;switch (theta){case'+':c = a + b;break;case'-':c = a - b;break;case'*':c = a*b;break;case'/':c = a / b;}return c;}ElemType EvaluateExpression() /* 有改动 */{ /* 算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈 */stack OPTR, OPND;ElemType a, b, d, x, theta;char c; /* 存放由键盘接收的字符串 */char z[6]; /* 存放整数字符串 */int i;create(&OPTR); /* 初始化运算符栈 */push(&OPTR, '='); /* =是表达式结束标志 */create(&OPND); /* 初始化运算数栈 */c = getchar();x = top(OPTR);while (c != '=' || x != '='){if (In(c)) /* 是7种运算符之一 */switch (Precede(x, c)){case'<':push(&OPTR, c); /* 栈顶元素优先权低 */c = getchar();break;case'=':x = top(OPTR); pop(&OPTR);/* 脱括号并接收下一字符 */c = getchar();break;case'>':theta = top(OPTR); pop(&OPTR); /* 退栈并将运算结果入栈 */b = top(OPND);  pop(&OPND);a = top(OPND);  pop(&OPND);push(&OPND, Operate(a, theta, b));}else if (c >= '0'&&c <= '9') /* c是操作数 */{i = 0;do{z[i] = c;i++;c = getchar();} while (c >= '0'&&c <= '9');z[i] = 0;d = atoi(z); /* 将字符串数组转为整型存于d */push(&OPND, d);}else /* c是非法字符 */{printf("ERROR3\n");exit(ERROR);}x = top(OPTR);}x = top(OPND);return x;}void main() /* 有改动 */{printf("请输入算术表达式,负数要用(0-正数)表示,并以=结束\n");printf("%d\n", EvaluateExpression());}
2.链栈

头文件

#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h> /* exit() *//* 函数结果状态代码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef int ElemType;struct LNode{ElemType data;struct LNode *next;};typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */typedef LinkList LinkStack; /* LinkStack是指向栈结点的指针类型 */Status create(LinkList *L);Status destroy(LinkList *L);Status clear(LinkList L);Status empty(LinkList L);int size(LinkList L);Status get(LinkList L, int i, ElemType *e);int find(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));Status prior(LinkList L, ElemType cur_e, ElemType *pre_e);Status next(LinkList L, ElemType cur_e, ElemType *next_e);Status insert(LinkList L, int i, ElemType e);Status delete(LinkList L, int i, ElemType *e);Status listTraverse(LinkList L, void(*vi)(ElemType));void insertAscend(LinkList L, ElemType e);void insertDescend(LinkList L, ElemType e);Status push(LinkList L, ElemType e);Status endInsert(LinkList L, ElemType e);Status pop(LinkList L);Status deleteTail(LinkList L, ElemType *e);Status deleteElem(LinkList L, ElemType e);Status replace(LinkList L, int i, ElemType e);Status creatAscend(LinkList *L, int n);Status creatDescend(LinkList *L, int n);Status top(LinkList L);Status traverse(LinkStack S, void(*visit)(ElemType)); 

实现文件

#include "stack_link.h"Status create(LinkList *L){ /* 操作结果:构造一个空的线性表L */*L = (LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */if (!*L) /* 存储分配失败 */exit(OVERFLOW);(*L)->next = NULL; /* 指针域为空 */return OK;}Status destroy(LinkList *L){ /* 初始条件:线性表L已存在。操作结果:销毁线性表L */LinkList q;while (*L){q = (*L)->next;free(*L);*L = q;}return OK;}Status clear(LinkList L) /* 不改变L */{ /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */LinkList p, q;p = L->next; /* p指向第一个结点 */while (p) /* 没到表尾 */{q = p->next;free(p);p = q;}L->next = NULL; /* 头结点指针域为空 */return OK;}Status empty(LinkList L){ /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */if (L->next) /* 非空 */return FALSE;elsereturn TRUE;}int size(LinkList L){ /* 初始条件:线性表L已存在。操作结果:返回L中数据元素个数 */int i = 0;LinkList p = L->next; /* p指向第一个结点 */while (p) /* 没到表尾 */{i++;p = p->next;}return i;}Status get(LinkList L, int i, ElemType *e) /* 算法2.8 */{ /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */int j = 1; /* j为计数器 */LinkList p = L->next; /* p指向第一个结点 */while (p&&j<i) /* 顺指针向后查找,直到p指向第i个元素或p为空 */{p = p->next;j++;}if (!p || j>i) /* 第i个元素不存在 */return ERROR;*e = p->data; /* 取第i个元素 */return OK;}int find(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)){ /* 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) *//* 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。 *//*           若这样的数据元素不存在,则返回值为0 */int i = 0;LinkList p = L->next;while (p){i++;if (compare(p->data, e)) /* 找到这样的数据元素 */return i;p = p->next;}return 0;}Status prior(LinkList L, ElemType cur_e, ElemType *pre_e){ /* 初始条件: 线性表L已存在 *//* 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, *//*           返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE */LinkList q, p = L->next; /* p指向第一个结点 */while (p->next) /* p所指结点有后继 */{q = p->next; /* q为p的后继 */if (q->data == cur_e){*pre_e = p->data;return OK;}p = q; /* p向后移 */}return INFEASIBLE;}Status next(LinkList L, ElemType cur_e, ElemType *next_e){ /* 初始条件:线性表L已存在 *//* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, *//*           返回OK;否则操作失败,next_e无定义,返回INFEASIBLE */LinkList p = L->next; /* p指向第一个结点 */while (p->next) /* p所指结点有后继 */{if (p->data == cur_e){*next_e = p->next->data;return OK;}p = p->next;}return INFEASIBLE;}Status insert(LinkList L, int i, ElemType e) /* 算法2.9。不改变L */{ /* 在带头结点的单链线性表L中第i个位置之前插入元素e */int j = 0;LinkList p = L, s;while (p&&j<i - 1) /* 寻找第i-1个结点 */{p = p->next;j++;}if (!p || j>i - 1) /* i小于1或者大于表长 */return ERROR;s = (LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */s->data = e; /* 插入L中 */s->next = p->next;p->next = s;return OK;}Status delete(LinkList L, int i, ElemType *e) /* 算法2.10。不改变L */{ /* 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 */int j = 0;LinkList p = L, q;while (p->next&&j<i - 1) /* 寻找第i个结点,并令p指向其前趋 */{p = p->next;j++;}if (!p->next || j>i - 1) /* 删除位置不合理 */return ERROR;q = p->next; /* 删除并释放结点 */p->next = q->next;*e = q->data;free(q);return OK;}Status listTraverse(LinkList L, void(*vi)(ElemType))/* vi的形参类型为ElemType,与bo2-1.c中相应函数的形参类型ElemType&不同 */{ /* 初始条件:线性表L已存在 *//* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */LinkList p = L->next;while (p){vi(p->data);p = p->next;}printf("\n");return OK;}/* bo2-9.c 单链表线性表(存储结构由c2-2.h定义)的扩展操作(11个) */void insertAscend(LinkList L, ElemType e){ /* 初始条件:按非降序排列的线性表L已存在。操作结果:在L中按非降序插入新的数据元素e */LinkList q = L, p = L->next;while (p&&e>p->data){q = p;p = p->next;}q->next = (LinkList)malloc(sizeof(struct LNode)); /* 插在q后 */q->next->data = e;q->next->next = p;}void insertDescend(LinkList L, ElemType e){ /* 初始条件:按非升序排列的线性表L已存在。操作结果:在L中按非升序插入新的数据元素e */LinkList q = L, p = L->next;while (p&&e<p->data){q = p;p = p->next;}q->next = (LinkList)malloc(sizeof(struct LNode)); /* 插在q后 */q->next->data = e;q->next->next = p;}Status push(LinkList L, ElemType e){ /* 初始条件:线性表L已存在。操作结果:在L的头部插入新的数据元素e,作为链表的第一个元素 */LinkList s;s = (LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */s->data = e; /* 给结点赋值 */s->next = L->next; /* 插在表头 */L->next = s;return OK;}Status endInsert(LinkList L, ElemType e){ /* 初始条件:线性表L已存在。操作结果:在L的尾部插入新的数据元素e,作为链表的最后一个元素 */LinkList p = L;while (p->next) /* 使p指向表尾元素 */p = p->next;p->next = (LinkList)malloc(sizeof(struct LNode)); /* 在表尾生成新结点 */p->next->data = e; /* 给新结点赋值 */p->next->next = NULL; /* 表尾 */return OK;}Status pop(LinkList L){ /* 初始条件:线性表L已存在,且有不少于1个元素 *//* 操作结果:删除L的第一个数据元素,并由e返回其值 */LinkList p = L->next;if (p){L->next = p->next;free(p);return OK;}else{puts("try to pop a element in a empty stack");exit(0);}}Status deleteTail(LinkList L, ElemType *e){ /* 初始条件:线性表L已存在,且有不少于1个元素 *//* 操作结果:删除L的最后一个数据元素,并用e返回其值 */LinkList p = L, q = NULL;if (!p->next) /* 链表为空 */return ERROR;while (p->next){q = p;p = p->next;}q->next = NULL; /* 新尾结点的next域设为NULL */*e = p->data;free(p);return OK;}Status deleteElem(LinkList L, ElemType e){ /* 删除表中值为e的元素,并返回TRUE;如无此元素,则返回FALSE */LinkList p = L, q;while (p){q = p->next;if (q&&q->data == e){p->next = q->next;free(q);return TRUE;}p = q;}return FALSE;}Status replace(LinkList L, int i, ElemType e){ /* 用e取代表L中第i个元素的值 */LinkList p = L;int j = 0;while (p->next&&j<i){j++;p = p->next;}if (j == i){p->data = e;return OK;}else /* 表中不存在第i个元素 */return ERROR;}Status creatAscend(LinkList *L, int n){ /* 按非降序建立n个元素的线性表 */int j;LinkList p, q, s;if (n <= 0)return ERROR;create(L);printf("请输入%d个元素:\n", n);s = (LinkList)malloc(sizeof(struct LNode)); /* 第一个结点 */scanf("%d", &s->data);s->next = NULL;(*L)->next = s;for (j = 1; j<n; j++){s = (LinkList)malloc(sizeof(struct LNode)); /* 其余结点 */scanf("%d", &s->data);q = *L;p = (*L)->next;while (p&&p->data<s->data) /* p没到表尾,且所指元素值小于新值 */{q = p;p = p->next; /* 指针后移 */}s->next = q->next; /* 元素插在q的后面 */q->next = s;}return OK;}Status creatDescend(LinkList *L, int n){ /* 按非升序建立n个元素的线性表 */int j;LinkList p, q, s;if (n <= 0)return ERROR;create(L);printf("请输入%d个元素:\n", n);s = (LinkList)malloc(sizeof(struct LNode)); /* 第一个结点 */scanf("%d", &s->data);s->next = NULL;(*L)->next = s;for (j = 1; j<n; j++){s = (LinkList)malloc(sizeof(struct LNode)); /* 其余结点 */scanf("%d", &s->data);q = *L;p = (*L)->next;while (p&&p->data>s->data) /* p没到表尾,且所指元素值大于新值 */{q = p;p = p->next; /* 指针后移 */}s->next = q->next; /* 元素插在q的后面 */q->next = s;}return OK;}ElemType top(LinkList L){ /* 返回表头元素的值 */LinkList p = L->next;if (!p) /* 空表 */return ERROR;else /* 非空表 */return p->data;}Status traverse(LinkStack S, void(*visit)(ElemType)){ /* 从栈底到栈顶依次对栈中每个元素调用函数visit()。 */ElemType e;LinkStack temp, p = S;create(&temp); /* 初始化temp栈 */while (p->next){e = top(p);push(temp, e);p = p->next;}listTraverse(temp, visit);return OK;}

测试文件一

#include "stack_link.h"void print(ElemType c){printf("%d ", c);}void main(){int j;LinkStack s;ElemType e;if (create(&s))for (j = 1; j <= 5; j++)push(s, 2 * j);printf("栈中的元素从栈底到栈顶依次为: ");traverse(s, print);e = top(s);pop(s);printf("弹出的栈顶元素为%d\n", e);printf("栈空否: %d(1:空 0:否)\n", empty(s));e = top(s);printf("当前栈顶元素为%d,栈的长度为%d\n", e, size(s));clear(s);printf("清空栈后,栈空否: %d(1:空 0:否),栈的长度为%d\n", empty(s), size(s));printf("是否销毁栈了: %d(1:是 0:否)\n", destroy(&s));}



0 0
原创粉丝点击