數據結構與算法

對象 ————————> 操作
線性表 ————————> 創建
遍歷
插入
刪除
查詢
————————> 進棧
出棧
隊列 插入
刪除
查詢

棧的操作

用一個素組實現棧

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. 當隊列爲空時,隊列的頭指針=隊列的尾指針;
  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)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章