數據結構----線性表順序和鏈式結構的使用(c)


PS:在學習數據結構之前,我相信很多博友也都學習過一些語言,比如說java,c語言,c++,web等,我們之前用的一些方法大都是封裝好的,就java而言,里面使用了大量的封裝好的方法,一些算法也大都寫好了,java還有三個特性,封裝、繼承、多態。當然這里不是講Java,這里主要是說內部結構,大家都知道數據結構有些東西是分為邏輯結構和物理結構的,物理結構有分為順序結構和鏈式結構,有不懂得可以百度百科,這里主要是分享線性表的順序結構。那么什么是線性表呢,線性表是最基本、最簡單、也是最常用的一種數據結構。線性表(linear list)是數據結構的一種,一個線性表是n個具有相同特性的數據元素的有限序列。

線性表

  • 順序表
  • 鏈式表

1:順序表分析

  •   結構體創建
  •   初始化順序表
  •   插入操作
  •   刪除操作
  •   查找操作
  •   修改操作

由於順序表比較簡單,這里解釋都在代碼中,在外就不在贅述。

1-1:結構體的創建

 

#define ElemType int
#define MAXSIZE 100     //定義變量不需要分號。
//創建線性表
typedef struct {
    ElemType elem[MAXSIZE];
    int length;        //長度
} SqList;

1-2:初始化順序表

int InitList(SqList &L) {
    // 初始化表,一個空表。
    L.length = 0;
    return 0;
}

1-3:操作方法

/**
 * @descibe 插入元素
 * @param L 線性表
 * @param pos 所在位置(並非角標)
 * @param data 插入元素
 * */
int ListInsert(SqList &L, int pos, ElemType data) {
    if (pos < 1 || pos > L.length + 1) {
        printf("插入的不合法");
        return -1;
    }
    int i;
    //在插入的同時,i要保證在pos以及pos后方,入1,2,3,4,5當在第3個插入時,須把原有的第三個數據以及以后數據后移一位,空出第三個位置。
    for (i = L.length; i >= pos; i--) {
        L.elem[i] = L.elem[i - 1];
    }
    L.elem[pos - 1] = data;
    L.length++;
    return 0;//
}
/**
 * 線性表中刪除操作
 * @param L 線性表
 * @param pos 所在位置(並非角標)
 * @param data 插入元素
 * */
int ListDelete(SqList &L, int pos, int data) {
    if (pos < 1 || pos > L.length) {
        printf("刪除角標不合法");
        return -1;
    }
    if (!(L.elem[pos - 1] == data)) {
        printf("沒有這個數字");
        return -1;
    }
    int i;
    //在插入的同時,i要保證在pos以及pos后方,入1,2,3,4,5當在第3個插入時,須把原有的第三個數據以及以后數據后移一位,空出第三個位置。
    for (i = pos; i <= L.length; i++) {
        L.elem[i - 1] = L.elem[i];
    }
    L.length--;
    return 0;//返回0表示成功;
}
//查找數據
int queryList(SqList L, int e) {
    //如果小於1證明沒有數據,則直接返回。
    if (L.length < 1) {
        printf("表中沒有數據");
        return -1;
    }
    for (int i = 0; i < L.length; i++) {
        if (L.elem[i] == e) {
            printf("找到該數據:%d角標為:%d \n", L.elem[i], i);
        }
    }
    return 0;
}

//修改數據
int xiugai(SqList &L, int pos, int e) {
    if (pos < 1 || pos > L.length) {
        printf("修改角標不合法");
        return -1;
    }
    L.elem[pos - 1] = e;
    return 0;

}
//打印全部數據
void PrintF(SqList L) {
    printf("打印表中所有元素\n");
    int i;
    for (i = 0; i < L.length; i++) {
        printf("%d\n", L.elem[i]);
    }
}

綜上所述:線性表和之前的數組類似,很容易理解。在使用的過程記得聲明一下方法(函數);

2:鏈表分析

  •   結構體創建
  •   初始化順序表
  •   插入操作
  •   刪除操作
  •   查找操作
  •   修改操作

需要注意的是這里的結構體需要一個指針,前一個結點的指針指向下一個結點,依次類推,最后一個指針指向NULL;

2-1:結構體創建

/**
 * @describe 創建一個結構體
 *  SLink *next指針;
 * *SLinkListL 創建一個結構體指針
 * */
typedef struct SLink {
    int data;
    struct SLink *next;
} SLink, *SLinkListL;

2-2:初始化鏈表

/**
 * @describe 初始化鏈表
 * */
SLinkListL initLinkL() {
    //1:分配一個空間
    SLinkListL sLinkListL = (SLinkListL) malloc(sizeof(SLink));
    //2:判斷是否創建成功
    if (!sLinkListL) {
        exit(-1);
    }
    sLinkListL->next = NULL;
    printf("初始化單鏈表成功\n");
    return sLinkListL;
}

2-3:操作--增刪該查

這里需要注意的是修改這個操作,找p的時候要找到要修改的p,而不是前一個結點,比如說,咱們在第二個位置插入的時候要找到第一個位置作為p,二修改的時候就要找到第二個位置,也就是說pos傳值的時候不用減一。

/**
 * @describe 插入操作
 *
 * @param L 鏈表類型
 * @param pos 插入位置
 * @param e 插入元素
 * */
int insertLinkL(SLinkListL &L, int pos, int e) {
    SLinkListL p = L;
    //判斷是否符合鏈表的長度;
    int i = 0;
    //判斷長度,尋找要插入的位置(前一位);
    while (p && i < pos-1) {
        p = p->next;
        i++;
    }
    //判斷長度是否超過pos
    if (!p || i > pos-1) {
        return 0;
    }
    //為新元素創建結點(分配空間)
    SLinkListL s = (SLinkListL) malloc(sizeof(SLink));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return 1;
}

/**
 * @describe 刪除操作
 * @param L 鏈表類型
 * @param pos 刪除位置
 * @param e 刪除存放元素
 * */
int deleteLinkL(SLinkListL &L, int pos, int *e) {
    SLinkListL p = L;
    //1:判斷位置
    int i = 0;
    while (p && i < pos-1) {
        p = p->next;
        i++;
    }
    if (!p || i > pos-1) {
        printf("刪除位置不合法\n");
        return -1;
    }
    //定義一個空的變量,用於存放p的指針,入a1,a2,a3,如果要刪除a2,則p指向a1,此時,把a1的next先交給s(暫存,此時代表a2(因為a1的指針是指向a2)),然后用s去取下一個指針(next)就是a3,
    SLinkListL s;//s為了釋放掉刪除元素的空間
    s = p->next;
    p->next = s->next;
    *e = s->data;//暫存
    free(s);
    printf("刪除成功\n");
    return 0;
}

/**
 * @describe 查找操作
 * @param L:鏈表類型
 * @param e:e查找元素
 * */
int queryLinkL(SLinkListL L, int e) {
    printf("查找元素為:%d",e);
    SLinkListL p = L;
    int i = 1;
    while (p) {
        p = p->next;
        if (p->data == e) {
            printf("找到元素%d\n", i);
            return 0;
        }
        i++;
    }
    printf("下標不合法/沒有找到該數據");
    return -1;
}

/**
 * @describe 修改操作
 * @param L:鏈表類型
 * @param i:修改元素的位置
 * @param e:修改元素值
 * */
int updataLinkL(SLinkListL &L, int pos, int e) {
    printf("修改數據為第:%d 個,值為:%d\n",pos,e);
    SLinkListL p = L;
    int i = 0;
    while (p && i < pos) {
        p = p->next;
        i++;
    }
    if (!p || i > pos) {
        printf("修改失敗--原因:修改的下標越界\n");
        return -1;
    }
    p->data = e;
    printf("修改成功\n");
    return 0;
}

void printLL(SLinkListL L) {
    printf("打印全部數據\n");
    SLinkListL p = L->next;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

綜上所述:只多了一個指針,一開始看估計還有有看不懂的地方,按照順序把代碼粘貼到你編輯器上,運行起來慢慢看。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM