InitStack(&S)
:初始化一个空栈SStackEmpty(S)
:判断一个栈是否为空,若栈S为空则返回true,否则返回falsePush(&S,x)
:进栈,若栈S未满,则将x加入使之成为新栈顶Pop(&S,%=&x)
:出栈,若栈S非空,则用x返回栈顶元素GetTop(S,&x)
:读栈顶元素,若栈S非空,则用x返回栈顶元素DestroyStack(&S)
:销毁栈,并释放栈S占用的存储空间#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //静态数组存放栈中元素
int top; //栈顶元素
}SqStack;
void testStack(){
SqStack S; //声明一个顺序栈(分配空间)
//连续的存储空间大小为 MaxSize*sizeof(ElemType)
}
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //静态数组存放栈中元素
int top; //栈顶元素
}SqStack;
//初始化栈
void InitStack(SqStack &S){
S.top = -1; //初始化栈顶指针
}
//判栈空
bool StackEmpty(SqStack S){
if(S.top == -1) //栈空
return true;
else //栈不空
return false;
}
//新元素进栈
bool Push(SqStack &S, ElemType x){
if(S.top == MaxSize - 1) //栈满
return false;
S.top = S.top + 1; //指针先加1
S.data[S.top] = x; //新元素入栈
/*
S.data[++S.top] = x;
*/
return true;
}
//出栈
bool Pop(SqStack &x, ElemType &x){
if(S.top == -1) //栈空
return false;
x = S.data[S.top]; //先出栈
S.top = S.top - 1; //栈顶指针减1
return true;
/*
x = S.data[S.top--];
*/
//只是逻辑上的删除,数据依然残留在内存里
}
//读栈顶元素
bool GetTop(SqStack S, ElemType &x){
if(S.top == -1)
return false;
x = S.data[S.top]; //x记录栈顶元素
return true;
}
void testStack(){
SqStack S; //声明一个顺序栈(分配空间)
InitStack(S);
//...
}
top==MaxSize
与链表类似,入栈和出栈的操作都在链表的表头进行
InitQueue(&Q)
: 初始化队列,构造一个空队列QDestroyQueue(&Q)
: 销毁队列,并释放队列Q所占用的内存空间EnQueue(&Q, x)
: 入队,若队列Q未满,将x加入,使之成为新的队尾DeQueue(&Q, &x)
: 出队,若队列Q非空,删除队头元素,并用x返回GetHead(Q,&x)
: 读队头元素,若队列Q非空,则将队头元素赋值给xQueueEmpty(Q)
: 判队列空,若队列Q为空,则返回true,否则返回false# define MaxSize 10; //定义队列中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //用静态数组存放队列元素
int front, rear; //队头指针和队尾指针
}SqQueue;
//初始化队列
void InitQueue(SqQueue &Q){
//初始化时,队头、队尾指针指向0
Q.rear = Q.front = 0;
}
// 判断队列是否为空
bool QueueEmpty(SqQueue 0){
if(Q.rear == Q.front) //队空条件
return true;
else
return false;
}
bool EnQueue(SqQueue &Q, ElemType x){
if((Q.rear+1)%MaxSize == Q.front) //队满
return false; //队满报错
Q.data[Q.rear] = x; //将x插入队尾
Q.rear = (Q.rear + 1) % MaxSize; //队尾指针加1取模
return true;
}
//出队,删除一个队头元素,用x返回
bool DeQueue(SqQueue &Q, ElemType &x){
if(Q.rear == Q.front) //队空报错
return false;
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize; //队头指针后移动
return true;
}
bool GetHead(SqQueue &Q, ElemType &x){
if(Q.rear == Q.front) //队空报错
return false;
x = Q.data[Q.front];
return true;
}
rear=front=0;
Q.rear==Q.front;
(Q.rear+1)%MaxSize == Q.front
(rear+MaxSize-front)%MaxSize;
#define MaxSize 10; //定义队列中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //用静态数组存放队列元素
int front, rear; //队头指针和队尾指针
int size;
}SqQueue;
rear=front=0;
size=0;
size++;
size--;
size==Maxsize;
size==0;
#define MaxSize 10; //定义队列中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //用静态数组存放队列元素
int front, rear; //队头指针和队尾指针
int tag; //最近进行的是删除/插入
}SqQueue;
rear=front=0;
tag=0;
tag=1;
tag=0;
rear==front&&tag==1;
rear==front&&tag==0;
typedef struct LinkNode{ //链式队列结点
ElemType data;
struct LinkNode *next;
}
typedef struct{ //链式队列
LinkNode *front, *rear; //队列的队头和队尾指针
}LinkQueue;
初始化
void InitQueue(LinkQueue &Q){
//初始化时,front、rear都指向头结点
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.front -> next = NULL;
}
//判断队列是否为空
bool IsEmpty(LinkQueue Q){
if(Q.front == Q.rear) //也可用 Q.front -> next == NULL
return true;
else
return false;
}
void InitQueue(LinkQueue &Q){
//初始化时,front、rear都指向NULL
Q.front = NULL;
Q.rear = NULL;
}
//判断队列是否为空
bool IsEmpty(LinkQueue Q){
if(Q.front == NULL)
return true;
else
return false;
}
入队
//新元素入队 (表尾进行)
void EnQueue(LinkQueue &Q, ElemType x){
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode)); //申请一个新结点
s->data = x;
s->next = NULL; //s作为最后一个结点,指针域指向NULL
Q.rear->next = s; //新结点插入到当前的rear之后
Q.rear = s; //表尾指针指向新的表尾
}
//新元素入队
void EnQueue(LinkQueue &Q, ElemType x){
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode)); //申请一个新结点
s->data = x;
s->next = NULL;
if(Q.front==NULL){ //在空队列中插入第一个元素
Q.front=s; //修改队头队尾指针
Q.rear=s;
}else{
Q.rear->next=s; //新结点插入到rear结点之后
Q.rear=s; //修改rear指针
}
}
出队
//队头元素出队
bool DeQueue(LinkQueue &Q, ElemType &x){
if(Q.front == Q.rear)
return false; //空队
LinkNode *p = Q.front->next; //p指针指向即将删除的结点
x = p->data;
Q.front->next = p->next; //修改头结点的next指针
if(Q.rear == p) //此次是最后一个结点出队
Q.rear = Q.front; //修改rear指针
free(p); //释放结点空间
return true;
}
//队头元素出队
bool DeQueue(LinkQueue &Q, ElemType &x){
if(Q.front == Q.rear)
return false; //空队
LinkNode *p = Q.front; //p指针指向即将删除的结点
x = p->data;
Q.front = p->next; //修改头结点的next指针
if(Q.rear == p){ //此次是最后一个结点出队
Q.rear==NULL:
Q.front==NULL;
}
free(p); //释放结点空间
return true;
}
#define MaxSize 10
typedef struct{
char data[MaxSize];
int top;
} SqStack;
//初始化栈
InitStack(SqStack &S)
//判断栈是否为空
bool StackEmpty(SqStack &S)
//新元素入栈
bool Push(SqStack &S, char x)
//栈顶元素出栈,用x返回
bool Pop(SqStack &S, char &x)
bool bracketCheck(char str[], int length){
SqStack S; //声明
InitStack(S); //初始化栈
for(int i=0; i<length; i++){
if(str[i] == '(' || str[i] == '[' || str[i] == '{'){
Push(S, str[i]); //扫描到左括号,入栈
}else{
if(StackEmpty(S)) //扫描到右括号,且当前栈空
return false; //匹配失败
char topElem; //存储栈顶元素
Pop(S, topElem); //栈顶元素出栈
if(str[i] == ')' && topElem != '(' )
return false;
if(str[i] == ']' && topElem != '[' )
return false;
if(str[i] == '}' && topElem != '{' )
return false;
}
}
StackEmpty(S); //栈空说明匹配成功
}
中缀表达式
(需要界限符)
后缀表达式 (逆波兰表达式)
“左优先”原则: 只要左边的运算符能先计算,就优先算左边的 (保证运算顺序唯一)
先出栈的是“右操作数”
前缀表达式 (波兰表达式)
“右优先”原则: 只要右边的运算符能先计算,就优先算右边的;
先出栈的是“左操作数”
4.中缀表达式的计算(用栈实现):两个算法的结合: 中缀转后缀 + 后缀表达式的求值
1. 初始化两个栈,操作数栈和运算符栈
2. 若扫描到操作数,压入操作数栈
3. 若扫描到运算符或界限符,则按照“中缀转后缀”相同的逻辑压入运算符栈 (期间也会弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈项元素并执行相应运算,运算结果再压回操作数栈)
数组是由n(n>=1)个相同类型的数据元素构成的有限序列,每个数据元素称为一个数组元素,每个元素在n个线性关系中的序号称为该元素的下标,下标的取值范围称为数组的维界
描述矩阵元素时,行、列号通常从1开始
描述数组时,通常下标从 0 开始
矩阵的压缩存储:为多个相同的非零元素只分配一个存储空间;对零元素不分配空间。
k = { i ( i − 1 ) 2 + j − 1 , i ≥ j ( 下三角区和主对角线元素 ) j ( j − 1 ) 2 + i − 1 , i < j ( 上三角区元素 a i , j = a j , i ) k= \left\{ \begin{array}{l} \frac{i(i-1)}{2}+j-1, \quad i \ge j \quad (下三角区和主对角线元素) \\ \frac{j(j-1)}{2}+i-1, \quad i
k = { i ( i − 1 ) 2 + j − 1 , i ≥ j ( 下三角区和主对角线元素 ) n ( n + 1 ) 2 , i < j ( 上三角区元素 a i , j = a j , i ) k= \left\{ \begin{array}{l} \frac{i(i-1)}{2}+j-1, \quad i \ge j \quad (下三角区和主对角线元素) \\ \frac{n(n+1)}{2}, \quad i
3. 三对角矩阵(带状矩阵)
1. 当 ∣ i − j ∣ > 1 |i-j|>1 ∣i−j∣>1时,有 a i , j = 0 ( 1 ≤ i , j ≤ n ) a_{i,j}=0 (1 \leq i,j \leq n) ai,j=0(1≤i,j≤n)
2. 策略:按行优先(或列优先) 原则,只存储带状部分
3. 元素下标对应关系:k为 a i , j a_{i,j} ai,j在一维数组中的下标 k=2i+j-3