對象 | ————————> | 操作 |
---|---|---|
線性表 | ————————> | 創建 |
遍歷 | ||
插入 | ||
刪除 | ||
查詢 | ||
棧 | ————————> | 進棧 |
出棧 | ||
隊列 | 插入 | |
樹 | 刪除 | |
圖 | 查詢 |
棧的操作
用一個素組實現棧
1.順序棧元素"入棧"
最初,棧是"空棧",即數組是空的,top 值爲初始值 -1:
我們默認數組下標爲 0 一端表示棧底:
依次存儲元素 2、3 和 4,最終,top 值變爲 3:
2.順序棧元素"出棧"
將圖 5中的元素 2 出棧,則需要先將元素 4 和元素 3 依次出棧。需要注意的是,當有數據出棧時,要將 top 做 -1 操作。
eg:實現進棧和出棧:
#include <stdio.h>
//元素elem進棧
int push(int* a,int top,int elem){
a[++top]=elem;
return top;
}
//數據元素出棧
int pop(int * a,int top){
if (top==-1) {
printf("空棧");
return -1;
}
printf("彈棧元素:%d\n",a[top]);
top--;
return top;
}
int main() {
int a[100];//創建一個數組作爲棧
int top=-1;//初始爲-1,然後++top就是從0開始的了
top=push(a, top, 1);
top=push(a, top, 2);
top=push(a, top, 3);
top=push(a, top, 4);
top=pop(a, top);
top=pop(a, top);
top=pop(a, top);
top=pop(a, top);
top=pop(a, top);
return 0;
}
程序的輸出結果爲:
隊列的操作
1.順序隊列簡單實現
入隊和出隊
順序隊列的缺點:
序隊列之前的數組存儲空間將無法再被使用,造成了空間浪費;
如果順序表申請的空間不足夠大,則直接造成程序中數組 a 溢出,產生溢出錯誤;
eg: 順序表,C 語言實現順序隊列
#include <stdio.h>
int enQueue(int *a,int rear,int data){
a[rear]=data;
rear++;
return rear;
}
void deQueue(int *a,int front,int rear){
//如果 front==rear,表示隊列爲空
while (front!=rear) {
printf("出隊元素:%d\n",a[front]);
front++;
}
}
int main() {
int a[100];
int front,rear;
//設置隊頭指針和隊尾指針,當隊列中沒有元素時,隊頭和隊尾指向同一塊地址
front=rear=0;
//入隊
rear=enQueue(a, rear, 1);
rear=enQueue(a, rear, 2);
rear=enQueue(a, rear, 3);
rear=enQueue(a, rear, 4);
//出隊
deQueue(a, front, rear);
return 0;
}
2.環狀順序隊列實現
優點:
使用此方法需要注意的是,順序隊列在判斷數組是否已滿時,出現下面情況:
- 當隊列爲空時,隊列的頭指針=隊列的尾指針;
- 當數組滿員時,(隊列的頭指針+1)=隊列的尾指針;
(rear+1)%max==front,犧牲一個存儲空間作爲判定條件)
eg:實現環狀順序隊列
#include <stdio.h>
#define max 5//表示順序表申請的空間大小
int enQueue(int *a,int front,int rear,int data){
//添加判斷語句,如果rear超過max,則直接將其從a[0]重新開始存儲,如果rear+1和front重合,則表示數組已滿
if ((rear+1)%max==front) {
printf("空間已滿");
return rear;
}
a[rear%max]=data;
rear++;
return rear;
}
int deQueue(int *a,int front,int rear){
//如果front==rear,表示隊列爲空
if(front==rear%max) {
printf("隊列爲空");
return front;
}
printf("%d ",a[front]);
//front不再直接 +1,而是+1後同max進行比較,如果=max,則直接跳轉到 a[0]
front=(front+1)%max;
return front;
}
int main() {
int a[max];
int front,rear;
//設置隊頭指針和隊尾指針,當隊列中沒有元素時,隊頭和隊尾指向同一塊地址
front=rear=0;
//入隊
rear=enQueue(a,front,rear, 1);
rear=enQueue(a,front,rear, 2);
rear=enQueue(a,front,rear, 3);
rear=enQueue(a,front,rear, 4);
//出隊
front=deQueue(a, front, rear);
//再入隊
rear=enQueue(a,front,rear, 5);
//再出隊
front=deQueue(a, front, rear);
//再入隊
rear=enQueue(a,front,rear, 6);
//再出隊
front=deQueue(a, front, rear);
front=deQueue(a, front, rear);
front=deQueue(a, front, rear);
front=deQueue(a, front, rear);
return 0;
}
3.鏈式隊列及基本操作
鏈式隊列的結構:
鏈式隊列數據入隊:
鏈式隊列數據出隊:
eg:鏈式隊列入隊和出隊
#include <stdio.h>
#include <stdlib.h>
//鏈表中的節點結構
typedef struct QNode{
int data;
struct QNode * next;
}QNode;
//創建鏈式隊列的函數
QNode * initQueue(){
//創建一個頭節點
QNode * queue=(QNode*)malloc(sizeof(QNode));
//對頭節點進行初始化
queue->next=NULL;
return queue;
}
QNode* enQueue(QNode * rear,int data){
//1、用節點包裹入隊元素
QNode * enElem=(QNode*)malloc(sizeof(QNode));
enElem->data=data;
enElem->next=NULL;
//使用尾插法向鏈隊列中添加數據元素
//2、新節點與rear節點建立邏輯關係
rear->next=enElem;
rear=enElem;
//返回新的rear,爲後續新元素入隊做準備
return rear;
}
QNode* DeQueue(QNode * top,QNode * rear){
if (top->next==NULL) {
printf("\n隊列爲空");
return rear;
}
QNode * p=top->next;
printf("%d ",p->data);
top->next=p->next;
if (rear==p) {
rear=top;
}
free(p);
return rear;
}
int main() {
QNode * queue,*top,*rear;
queue=top=rear=initQueue();//創建頭結點
//向鏈隊列中添加結點,使用尾插法添加的同時,隊尾指針需要指向鏈表的最後一個元素
rear=enQueue(rear, 1);
rear=enQueue(rear, 2);
rear=enQueue(rear, 3);
rear=enQueue(rear, 4);
//入隊完成,所有數據元素開始出隊列
rear=DeQueue(top, rear);
rear=DeQueue(top, rear);
rear=DeQueue(top, rear);
rear=DeQueue(top, rear);
rear=DeQueue(top, rear);
return 0;
}
樹
樹的分類 |
---|
普通樹(節點數目可以爲0,1,2,3) |
二叉樹(節點數目可以爲0,1,2) |
完全二叉樹(最後一行節點需要從左到右) |
滿二叉樹(節點的數目爲2) |
樹的表示 | ~ |
---|---|
雙親表示法 | (順序數組) |
孩子表示法 | (順序表+鏈表) |
雙親孩子表示法 | (順序表+順序表+鏈表) |
孩子兄弟表示法 |
樹的遍歷 |
---|
先序遍歷 |
中序遍歷 |
後序遍歷 |
樹的性質:樹的節點+樹的深度(高)+樹的度
二叉樹的性質:
1.二叉樹中,第 i 層最多有 2i-1 個結點。(第一層只有一個根節點)
2.如果二叉樹的深度爲 h,那麼此二叉樹最多有 2h-1 個結點。(第一層只有一個根節點)
3.二叉樹中,終端結點數(葉子結點數)爲 n0,度爲 2 的結點數爲 n2,則 n0=n2+1。(葉節點的數量=度爲2的數量+1(根節點數量))
(除了度爲 0 的葉子結點和度爲 2 的結點,剩下的就是度爲 1 的結點(設爲 n1),那麼總結點 n=n0+n1+n2。)
圖
圖(有向,無向,帶權(網))
圖的分類 | ~ |
---|---|
完全圖 | 圖中各個頂點都與除自身外的其他頂點有關係(一點發散到各個點) |
連通圖 | 各個節點都是連接通的圖 |
完全圖:具有 n 個頂點的完全圖,圖中邊的數量爲 n(n-1)/2;而對於具有 n 個頂點的有向完全圖,圖中弧的數量爲 n(n-1)。