主頁 > 作業系統 > 查找演算法之順序查找,折半查找,二叉查找樹

查找演算法之順序查找,折半查找,二叉查找樹

2021-01-11 11:46:44 作業系統

目錄
  • 查找表的概念
  • 順序查找
  • 折半查找
    • 折半查找演算法
  • 二叉查找樹
    • 二叉查找樹概念
    • 使用二叉排序樹查找關鍵字
    • 二叉排序樹中插入關鍵字
    • 二叉排序樹中洗掉關鍵字

查找表的概念

??查找表是由同一型別的資料元素構成的集合,例如電話號碼簿和字典都可以看作是一張查找表,
??在查找表中只做查找操作,而不改動表中資料元素,稱此類查找表為靜態查找表;反之,在查找表中做查找操作的同時進行插入資料或者洗掉資料的操作,稱此類表為動態查找表,

順序查找

??順序查找的查找程序為:從表中的最后一個資料元素開始,逐個同記錄的關鍵字做比較,如果匹配成功,則查找成功;反之,如果直到表中第一個關鍵字查找完也沒有成功匹配,則查找失敗
同時,在程式中初始化創建查找表時,由于是順序存盤,所以將所有的資料元素存盤在陣列中,但是把第一個位置留給了用戶用于查找的關鍵字,例如,在順序表{1,2,3,4,5,6}中查找資料元素值為 7 的元素,則添加后的順序表為:
在這里插入圖片描述
????????????圖1
??順序表的一端添加用戶用于搜索的關鍵字,稱作“監視哨”,
??圖 1 中監視哨的位置也可放在資料元素 6 的后面(這種情況下,整個查找的順序應有逆向查找改為順序查找),
??放置好監視哨之后,順序表遍歷從沒有監視哨的一端依次進行,如果查找表中有用戶需要的資料,則程式輸出該位置;反之,程式會運行至監視哨,此時匹配成功,程式停止運行,但是結果是查找失敗,
代碼實作:

/*
 * @Description: 順序查找演算法
 * @Version: V1.0
 * @Autor: Carlos
 * @Date: 2020-05-22 15:52:11
 * @LastEditors: Carlos
 * @LastEditTime: 2020-06-03 16:56:06
 */ 
#include <stdio.h>
#include <stdlib.h>
#define keyType int
typedef struct {
    //查找表中每個資料元素的值
    keyType key;
    //如果需要,還可以添加其他屬性
}ElemType;

typedef struct{
    //存放查找表中資料元素的陣列
    ElemType *elem;
    //記錄查找表中資料的總數量
    int length;
}SSTable;
/**
 * @Description: 創建查找表
 * @Param: SSTable **st 指向結構體指標的指標,即指標變數的指標,int length 創建的二叉樹的長度
 * @Return: 無
 * @Author: Carlos
 */
void Create(SSTable **st,int length){
    (*st)=(SSTable*)malloc(sizeof(SSTable));
    (*st)->length=length;
    //結構體指標分配空間
    (*st)->elem =(ElemType*)malloc((length+1)*sizeof(ElemType));
    printf("輸入表中的資料元素:\n");
    //根據查找表中資料元素的總長度,在存盤時,從陣列下標為 1 的空間開始存盤資料
    for (int i=1; i<=length; i++) {
        scanf("%d",&((*st)->elem[i].key));
    }
}
/**
 * @Description: 查找表查找的功能函式,其中key為關鍵字
 * @Param: SSTable *st指向結構體變數的指標,keyType key 要查找的元素
 * @Return: key在查找表中的位置
 * @Author: Carlos
 */
int Search_seq(SSTable *st,keyType key){
    //將關鍵字作為一個資料元素存放到查找表的第一個位置,起監視哨的作用
    st->elem[0].key=key;
    int i=st->length;
    //從查找表的最后一個資料元素依次遍歷,一直遍歷到陣列下標為0
    while (st->elem[i].key!=key) {
        i--;
    }
    //如果 i=0,說明查找失敗;反之,回傳的是含有關鍵字key的資料元素在查找表中的位置
    return i;
}
int main(int argc, const char * argv[]) {
    SSTable *st;
    Create(&st, 6);
    getchar();
    printf("請輸入查找資料的關鍵字:\n");
    int key;
    scanf("%d",&key);
    int location=Search_seq(st, key);
    if (location==0) {
        printf("查找失敗");
    }else{
        printf("資料在查找表中的位置為:%d",location);
    }
    return 0;
}

折半查找

??折半查找,也稱二分查找,在某些情況下相比于順序查找,使用折半查找演算法的效率更高,但是該演算法的使用的前提是靜態查找表中的資料必須是有序的,
??例如,在{5,21,13,19,37,75,56,64,88 ,80,92}這個查找表使用折半查找演算法查找資料之前,需要首先對該表中的資料按照所查的關鍵字進行排序:{5,13,19,21,37,56,64,75,80,88,92},
??在折半查找之前對查找表按照所查的關鍵字進行排序的意思是:若查找表中存盤的資料元素含有多個關鍵字時,使用哪種關鍵字做折半查找,就需要提前以該關鍵字對所有資料進行排序,

折半查找演算法

??對靜態查找表{5,13,19,21,37,56,64,75,80,88,92}采用折半查找演算法查找關鍵字為 21 的程序為:
在這里插入圖片描述
??????????????圖2
后一個關鍵字,指標 mid 指向處于 low 和 high 指標中間位置的關鍵字,在查找的程序中每次都同 mid 指向的關鍵字進行比較,由于整個表中的資料是有序的,因此在比較之后就可以知道要查找的關鍵字的大致位置,
??例如在查找關鍵字 21 時,首先同 56 作比較,由于21 < 56,而且這個查找表是按照升序進行排序的,所以可以判定如果靜態查找表中有 21 這個關鍵字,就一定存在于 low 和 mid 指向的區域中間,
??因此,再次遍歷時需要更新 high 指標和 mid 指標的位置,令 high 指標移動到 mid 指標的左側一個位置上,同時令 mid 重新指向 low 指標和 high 指標的中間位置,如圖3所示:
在這里插入圖片描述
??????????????圖3
??同樣,用 21 同 mid 指標指向的 19 作比較,19 < 21,所以可以判定 21 如果存在,肯定處于 mid 和 high 指向的區域中,所以令 low 指向 mid 右側一個位置上,同時更新 mid 的位置,
在這里插入圖片描述
??????????????圖4
??當第三次做判斷時,發現 mid 就是關鍵字 21 ,查找結束,
??注意:在做查找的程序中,如果 low 指標和 high 指標的中間位置在計算時位于兩個關鍵字中間,即求得 mid 的位置不是整數,需要統一做取整操作,
??折半查找的實作代碼:

/*
 * @Description: 折半查找.前提是靜態查找表中的資料必須是有序的,
 * @Version: V1.0
 * @Autor: Carlos
 * @Date: 2020-05-22 16:09:01
 * @LastEditors: Carlos
 * @LastEditTime: 2020-06-03 16:58:14
 */ 
#include <stdio.h>
#include <stdlib.h>
#define keyType int
typedef struct {
    //查找表中每個資料元素的值
    keyType key;
    //如果需要,還可以添加其他屬性
}ElemType;

typedef struct{
    //存放查找表中資料元素的陣列
    ElemType *elem;
    //記錄查找表中資料的總數量
    int length;
}SSTable;
/**
 * @Description: 創建查找表
 * @Param: SSTable **st 指向結構體指標的指標,即指標變數的指標,int length 創建的二叉樹的長度
 * @Return: 無
 * @Author: Carlos
 */
void Create(SSTable **st,int length){
    (*st)=(SSTable*)malloc(sizeof(SSTable));
    (*st)->length=length;
    (*st)->elem = (ElemType*)malloc((length+1)*sizeof(ElemType));
    printf("輸入表中的資料元素:\n");
    //根據查找表中資料元素的總長度,在存盤時,從陣列下標為 1 的空間開始存盤資料
    for (int i=1; i<=length; i++) {
        scanf("%d",&((*st)->elem[i].key));
    }
}
//折半查找演算法
/**
 * @Description: 折半查找演算法
 * @Param: SSTable *ST 指向結構體的指標,keyType key 要插入的元素
 * @Return: 成功的回傳key在查找表中的位置,否則回傳0
 * @Author: Carlos
 */
int Search_Bin(SSTable *ST,keyType key){
    //初始狀態 low 指標指向第一個關鍵字
    int low=1;
    //high 指向最后一個關鍵字
    int high=ST->length;
    int mid;
    while (low<=high) {
        //int 本身為整形,所以,mid 每次為取整的整數
        mid=(low+high)/2;
        //如果 mid 指向的同要查找的相等,回傳 mid 所指向的位置
        if (ST->elem[mid].key==key)
        {
            return mid;
        }
        //如果mid指向的關鍵字較大,則更新 high 指標的位置
        else if(ST->elem[mid].key>key)
        {
            high=mid-1;
        }
        //反之,則更新 low 指標的位置
        else{
            low=mid+1;
        }
    }
    return 0;
}

int main(int argc, const char * argv[]) {
    SSTable *st;
    Create(&st, 11);
    getchar();
    printf("請輸入查找資料的關鍵字:\n");
    int key;
    scanf("%d",&key);
    int location=Search_Bin(st, key);
    //如果回傳值為 0,則證明查找表中未查到 key 值,
    if (location==0) {
        printf("查找表中無該元素");
    }else{
        printf("資料在查找表中的位置為:%d",location);
    }
    return 0;
}

二叉查找樹

??動態查找表中做查找操作時,若查找成功可以對其進行洗掉;如果查找失敗,即表中無該關鍵字,可以將該關鍵字插入到表中,
??動態查找表的表示方式有多種,本節介紹一種使用樹結構表示動態查找表的實作方法——二叉排序樹(又稱為“二叉查找樹”),

二叉查找樹概念

??二叉排序樹要么是空二叉樹,要么具有如下特點:

  • 二叉排序樹中,如果其根結點有左子樹,那么左子樹上所有結點的值都小于根結點的值;
  • 二叉排序樹中,如果其根結點有右子樹,那么右子樹上所有結點的值都大小根結點的值;
  • 二叉排序樹的左右子樹也要求都是二叉排序樹;

??例如,圖 5 就是一個二叉排序樹:
在這里插入圖片描述
??????????????圖5

使用二叉排序樹查找關鍵字

??二叉排序樹中查找某關鍵字時,查找程序類似于次優二叉樹,在二叉排序樹不為空樹的前提下,首先將被查找值同樹的根結點進行比較,會有 3 種不同的結果:

  1. 如果相等,查找成功;
  2. 如果比較結果為根結點的關鍵字值較大,則說明該關鍵字可能存在其左子樹中;
  3. 如果比較結果為根結點的關鍵字值較小,則說明該關鍵字可能存在其右子樹中;
    實作函式為:(運用遞回的方法)
/**
 * @Description: 二叉排序樹查找演算法
 * @Param: BiTree T  KeyType key  BiTree f BiTree *p
 * @Return: 洗掉成功 TRUE 洗掉失敗 FALSE
 * @Author: Carlos
 */
int SearchBST(BiTree T, KeyType key, BiTree f, BiTree *p)
{
    //如果 T 指標為空,說明查找失敗,令 p 指標指向查找程序中最后一個葉子結點,并回傳查找失敗的資訊
    if (!T)
    {
        *p = f;
        return FALSE;
    }
    //如果相等,令 p 指標指向該關鍵字,并回傳查找成功資訊
    else if (key == T->data)
    {
        *p = T;
        return TRUE;
    }
    //如果 key 值比 T 根結點的值小,則查找其左子樹;反之,查找其右子樹
    else if (key < T->data)
    {
        return SearchBST(T->lchild, key, T, p);
    }
    else
    {
        return SearchBST(T->rchild, key, T, p);
    }
}

二叉排序樹中插入關鍵字

??二叉排序樹本身是動態查找表的一種表示形式,有時會在查找程序中插入或者洗掉表中元素,當因為查找失敗而需要插入資料元素時,該資料元素的插入位置一定位于二叉排序樹的葉子結點,并且一定是查找失敗時訪問的最后一個結點的左孩子或者右孩子,
??例如,在圖 1 的二叉排序樹中做查找關鍵字 1 的操作,當查找到關鍵字 3 所在的葉子結點時,判斷出表中沒有該關鍵字,此時關鍵字 1 的插入位置為關鍵字 3 的左孩子,
??所以,二叉排序樹表示動態查找表做插入操作,只需要稍微更改一下上面的代碼就可以實作,具體實作代碼為:

/**
 * @Description: 二叉排序樹查找演算法
 * @Param: BiTree T  KeyType key  BiTree f BiTree *p
 * @Return: 洗掉成功 TRUE 洗掉失敗 FALSE
 * @Author: Carlos
 */
int SearchBST(BiTree T, KeyType key, BiTree f, BiTree *p)
{
    //如果 T 指標為空,說明查找失敗,令 p 指標指向查找程序中最后一個葉子結點,并回傳查找失敗的資訊
    if (!T)
    {
        *p = f;
        return FALSE;
    }
    //如果相等,令 p 指標指向該關鍵字,并回傳查找成功資訊
    else if (key == T->data)
    {
        *p = T;
        return TRUE;
    }
    //如果 key 值比 T 根結點的值小,則查找其左子樹;反之,查找其右子樹
    else if (key < T->data)
    {
        return SearchBST(T->lchild, key, T, p);
    }
    else
    {
        return SearchBST(T->rchild, key, T, p);
    }
}
/**
 * @Description: 二叉樹插入函式
 * @Param: BiTree *T 二叉樹結構體指標的指標  ElemType e 要插入的元素
 * @Return: 洗掉成功 TRUE 洗掉失敗 FALSE
 * @Author: Carlos
 */
int InsertBST(BiTree *T, ElemType e)
{
    BiTree p = NULL;
    //如果查找不成功,需做插入操作
    if (!SearchBST((*T), e, NULL, &p))
    {
        //初始化插入結點
        BiTree s = (BiTree)malloc(sizeof(BiTree));
        s->data = https://www.cnblogs.com/dongxb/p/e;
        s->lchild = s->rchild = NULL;
        //如果 p 為NULL,說明該二叉排序樹為空樹,此時插入的結點為整棵樹的根結點
        if (!p)
        {
            *T = s;
        }
        //如果 p 不為 NULL,則 p 指向的為查找失敗的最后一個葉子結點,只需要通過比較 p 和 e 的值確定 s 到底是 p 的左孩子還是右孩子
        else if (e < p->data)
        {
            p->lchild = s;
        }
        else
        {
            p->rchild = s;
        }
        return TRUE;
    }
    //如果查找成功,不需要做插入操作,插入失敗
    return FALSE;
}

??通過使用二叉排序樹對動態查找表做查找和插入的操作,同時在中序遍歷二叉排序樹時,可以得到有關所有關鍵字的一個有序的序列,
??例如,假設原二叉排序樹為空樹,在對動態查找表 {3,5,7,2,1} 做查找以及插入操作時,可以構建出一個含有表中所有關鍵字的二叉排序樹,程序如圖6 所示:
在這里插入圖片描述
??????????????圖6
??通過不斷的查找和插入操作,最終構建的二叉排序樹如圖 6(5) 所示,當使用中序遍歷演算法遍歷二叉排序樹時,得到的序列為:1 2 3 5 7 ,為有序序列,
一個無序序列可以通過構建一棵二叉排序樹,從而變成一個有序序列,

二叉排序樹中洗掉關鍵字

??在查找程序中,如果在使用二叉排序樹表示的動態查找表中洗掉某個資料元素時,需要在成功洗掉該結點的同時,依舊使這棵樹為二叉排序樹,
??假設要洗掉的為結點 p,則對于二叉排序樹來說,需要根據結點 p 所在不同的位置作不同的操作,有以下 3 種可能:

  1. 結點 p 為葉子結點,此時只需要洗掉該結點,并修改其雙親結點的指標即可;
  2. 結點 p 只有左子樹或者只有右子樹,此時只需要將其左子樹或者右子樹直接變為結點 p 雙親結點的左子樹即可;
  3. 結點 p 左右子樹都有,此時有兩種處理方式:
    ??(1).令結點 p 的左子樹為其雙親結點的左子樹;結點 p 的右子樹為其自身直接前驅結點的右子樹,如圖7所示;
    在這里插入圖片描述
    ??????????????圖7
    ??(2)用結點 p 的直接前驅(或直接后繼)來代替結點 p,同時在二叉排序樹中對其直接前驅(或直接后繼)做洗掉操作,如圖 8 為使用直接前驅代替結點 p:
    在這里插入圖片描述
    ??????????????圖8
    ??圖 8中,在對左圖進行中序遍歷時,得到的結點 p 的直接前驅結點為結點 s,所以直接用結點 s 覆寫結點 p,由于結點 s 還有左孩子,根據第 2 條規則,直接將其變為雙親結點的右孩子,
    ??具體實作代碼:(可運行)
/*
 * @Description: 二叉查找樹
 * @Version: V1.0
 * @Autor: Carlos
 * @Date: 2020-06-02 15:50:31
 * @LastEditors: Carlos
 * @LastEditTime: 2020-06-03 16:49:46
 */
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define ElemType int
#define KeyType int
/* 二叉排序樹的節點結構定義 */
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
/**
 * @Description: 二叉排序樹查找演算法
 * @Param: BiTree T  KeyType key  BiTree f BiTree *p
 * @Return: 洗掉成功 TRUE 洗掉失敗 FALSE
 * @Author: Carlos
 */
int SearchBST(BiTree T, KeyType key, BiTree f, BiTree *p)
{
    //如果 T 指標為空,說明查找失敗,令 p 指標指向查找程序中最后一個葉子結點,并回傳查找失敗的資訊
    if (!T)
    {
        *p = f;
        return FALSE;
    }
    //如果相等,令 p 指標指向該關鍵字,并回傳查找成功資訊
    else if (key == T->data)
    {
        *p = T;
        return TRUE;
    }
    //如果 key 值比 T 根結點的值小,則查找其左子樹;反之,查找其右子樹
    else if (key < T->data)
    {
        return SearchBST(T->lchild, key, T, p);
    }
    else
    {
        return SearchBST(T->rchild, key, T, p);
    }
}
/**
 * @Description: 二叉樹插入函式
 * @Param: BiTree *T 二叉樹結構體指標的指標  ElemType e 要插入的元素
 * @Return: 洗掉成功 TRUE 洗掉失敗 FALSE
 * @Author: Carlos
 */
int InsertBST(BiTree *T, ElemType e)
{
    BiTree p = NULL;
    //如果查找不成功,需做插入操作
    if (!SearchBST((*T), e, NULL, &p))
    {
        //初始化插入結點
        BiTree s = (BiTree)malloc(sizeof(BiTree));
        s->data = https://www.cnblogs.com/dongxb/p/e;
        s->lchild = s->rchild = NULL;
        //如果 p 為NULL,說明該二叉排序樹為空樹,此時插入的結點為整棵樹的根結點
        if (!p)
        {
            *T = s;
        }
        //如果 p 不為 NULL,則 p 指向的為查找失敗的最后一個葉子結點,只需要通過比較 p 和 e 的值確定 s 到底是 p 的左孩子還是右孩子
        else if (e < p->data)
        {
            p->lchild = s;
        }
        else
        {
            p->rchild = s;
        }
        return TRUE;
    }
    //如果查找成功,不需要做插入操作,插入失敗
    return FALSE;
}
/**
 * @Description: 洗掉節點的函式
 * @Param: BiTree *p 指向結構體指標的指標
 * @Return: 洗掉成功 TRUE
 * @Author: Carlos
 */
int Delete(BiTree *p)
{
    BiTree q, s;
    //情況 1,結點 p 本身為葉子結點,直接洗掉即可
    if (!(*p)->lchild && !(*p)->rchild)
    {
        *p = NULL;
    }
    //左子樹為空,只需用結點 p 的右子樹根結點代替結點 p 即可;
    else if (!(*p)->lchild)
    {
        q = *p;
        *p = (*p)->rchild;
        free(q);
        q = NULL;
    }
    //右子樹為空,只需用結點 p 的左子樹根結點代替結點 p 即可;
    else if (!(*p)->rchild)
    {
        q = *p;
        //這里不是指標 *p 指向左子樹,而是將左子樹存盤的結點的地址賦值給指標變數 p
        *p = (*p)->lchild;
        free(q);
        q = NULL;
    }
    //左右子樹均不為空,采用第 2 種方式
    else
    {
        q = *p;
        s = (*p)->lchild;
        //遍歷,找到結點 p 的直接前驅
        while (s->rchild)
        {
            //指向p節點左子樹最右邊節點的前一個,保留下來
            q = s;
            s = s->rchild;
        }
        //直接改變結點 p 的值
        (*p)->data = s->data;
        //判斷結點 p 的左子樹 s 是否有右子樹,分為兩種情況討論  如果有右子樹,s一定會指向右子樹的葉子節點,q 此時指向的是葉子節點的父節點, q != *p二者不等說明有右子樹
        if (q != *p)
        {
            //若有,則在洗掉直接前驅結點的同時,令前驅的左孩子結點改為 q 指向結點的孩子結點
            q->rchild = s->lchild;
        }
        else
        //q == *p ==NULL 說明沒有右子樹
        {
            //否則,直接將左子樹上移即可
            q->lchild = s->lchild;
        }
        free(s);
        s = NULL;
    }
    return TRUE;
}
/**
 * @Description: 洗掉二叉樹中的元素
 * @Param: BiTree *T 指向二叉樹結構體的指標 int key 要洗掉的元素
 * @Return: 洗掉成功 TRUE 洗掉失敗 FALSE
 * @Author: Carlos
 */
int DeleteBST(BiTree *T, int key)
{
    if (!(*T))
    { //不存在關鍵字等于key的資料元素
        return FALSE;
    }
    else
    {
        if (key == (*T)->data)
        {
            Delete(T);
            return TRUE;
        }
        else if (key < (*T)->data)
        {
            //使用遞回的方式
            return DeleteBST(&(*T)->lchild, key);
        }
        else
        {
            return DeleteBST(&(*T)->rchild, key);
        }
    }
}
/**
 * @Description: 中序遍歷輸出二叉樹
 * @Param: BiTree t 結構體變數
 * @Return: 無
 * @Author: Carlos
 */
void order(BiTree t) 
{
    if (t == NULL)
    {
        return;
    }
    order(t->lchild);
    printf("%d ", t->data);
    order(t->rchild);
}
int main()
{
    int i;
    int a[5] = {3, 4, 2, 5, 9};
    BiTree T = NULL;
    for (i = 0; i < 5; i++)
    {
        InsertBST(&T, a[i]);
    }
    printf("中序遍歷二叉排序樹:\n");
    order(T);
    printf("\n");
    printf("洗掉3后,中序遍歷二叉排序樹:\n");
    DeleteBST(&T, 3);
    order(T);
}

有任何問題,均可通過公告中的二維碼聯系我

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/247014.html

標籤:嵌入式

上一篇:Kubernetes K8S之CPU和記憶體資源限制詳解

下一篇:哈希表基本概念介紹及哈希沖突的處理方法(附原始碼)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more