栈
用一个数组来表示栈,栈的属性就是先进后出,利用数组的话就是头固定,进出数据从同一头进出
属性也就是top(s)表示最新插入的那个元素(初始值为-1),n---栈的大小 注意:这里是最新插入的那个元素,注意与队列的不同
操作也就是两个Push(S,x)和Pop(S)
Push(S,x)将元素x插入到栈S的尾部去
Push(S,x)
-1- if tail(S) == n-1 (注意:这里表示数组大小是从0变化到n-1的)
-2- error!!! 上溢出
-3- else
-4- top(S)← top(s)+1
-5- S[top(S)]←x
Pop(S)
-1- if top(S) == -1
-2- error!!! 下溢出
-3- else
-4- top(S)←top(S)-1
-5- return S[top(S)+1]
#include<cstdio>
const int STACK_SIZE = 10;
struct stack
{
int s [STACK_SIZE];
void push(int a);
int pop();
int top;
};
void stack::push(int a)
{
if (top==STACK_SIZE-1)
{
printf("There is no place for the new number!!!\n");
return;
}
top++;
s[top] = a;
}
int stack::pop()
{
if(top == -1)
{
printf("There is no number for pop!!!\n");
return -1;
}
top--;
return s[top+1];
}
int main()
{
stack b;
b.top = -1;
for(int i =0; i<10; i++)
b.push(i);
printf("%d\n",b.pop());
printf("%d\n",b.pop());
return 0;
}
队列
队列不同于栈,它的规则为先进先出,利用数组表示就是从一头进从另一头出
它的属性为 head(S)---队列的第一个元素(初始值设为-1,表示还从未有元素入队),tail(S)---队列中下一个插入元素的位置(初始值为0),unreel---表面是否发生了回卷,unreel=0,未发生回卷,unreel=1,发生回卷
他的操作为Enqueue(S,x)和Dequeue(S)
Enqueue(S,x)将x插入到队列的队尾
Enqueue(S,x)
-1- if unreel==1&&head(S) == tail(S)
-2- error!!!上溢出
-3- else
-4- if head(S) ==-1
-5- head(S) = 0
-6- S[tail(S)]←x
-7- if tail(S)==n-1
-8- unreel = 1
-9- tail(S)←(tail(S)+1)%n
Dequeue(S)
-1- if unreel==0&&head(S)==tail(S)
-2- error!!!下溢出
-3- else
-4- if head(S)==n-1
-5- unreel = 0;
-6- head(S) = (head(S)+1)%n
-7- return head(S)==0?S[n-1]:S[head(S)-1]
#include<cstdio>
const int QUEUE_SIZE = 10;
struct Queue
{
int q[QUEUE_SIZE];
int head;
int tail;
int unreel; //unreel=0---未发生回卷,unreel=1---发生回卷
void enqueue(int a);
int dequeue();
void init();
};
void Queue::init()
{
head = -1;
tail = 0;
unreel = 0;
}
void Queue::enqueue(int a)
{
if(unreel==1&& head ==tail)
{
printf("there is no place in the queue for the new number!!!\n");
return;
}
if(head == -1)
head = 0;
q[tail] = a;
unreel = (tail+1)/QUEUE_SIZE;
tail = (tail+1)%QUEUE_SIZE;
}
int Queue::dequeue()
{
if(unreel == 0 && head == tail)
{
printf("there is no number for dequeue!!!\n");
return -1;
}
if(head+1 == QUEUE_SIZE)
unreel = 0;
head = (head+1)%QUEUE_SIZE;
return head==0?q[QUEUE_SIZE-1]:q[head-1];
}
int main()
{
Queue b;
b.init();
for(int i =0; i<10; i++)
b.enqueue(i);
printf("%d\n",b.dequeue());
printf("%d\n",b.dequeue());
return 0;
}
链表
链表就是利用指针将一系列分散的对象连接到一起,链表可以有很多种:单链表、双链表、循环链表
双向链由三部分组成:key、prev、next:key---关键值,prev---指向前一个节点的指针,next---指向后一个节点的指针。
如果prev(x)==NIL,那么这个节点x就是头
如果next(x)==NIL,那么这个节点x就是尾
可以这样判断头和尾,也可以使用卫兵来表示头和尾
用nil来表示哨兵,那么next(nil)指向链表的头,而prev(nil)指向链表的尾部,而且尾的next指向nil,链表头的prev指向nil。
单向链表由两部分组成:key、next。
链表的操作分为:Search(L,k)、Insert(L,x)、Delete(L,x)
Search(L,k)
-1- i←next(nil)
-2- while i != nil && k != key(i)
-3- i←next(i)
-4- return i
Insert(L,x)
-1- next(x)←next(nil)
-2- prev(next(nil))←x
-3- next(nil)←x
Delete(L,k)
-1- next(prev(k))←next(k)
-2- prev(next(k))←prev(k)