《數據結構教程》2.1-2.2 順序表

定義

線性表 是由 n 個屬於 同一數據對象 的數據元素組成的 有限 序列。除序列的第一個數據元素與最後一個數據元素以外,其餘任何一個數據元素有且僅有一個直接前驅元素,有且僅有一個直接後繼元素。數組

線性表的存儲結構能夠採用 順序存儲結構鏈式存儲結構,採用順序存儲結構的線性表又稱爲 順序表bash

順序表

  • 特色:邏輯位置相鄰的數據元素在物理位置上也必定相鄰。

只要肯定了首地址,線性表中任意一個數據元素能夠隨機存取。所以,能夠稱線性表的存儲結構爲一種隨機存取的存儲結構。優化

  • 優勢:簡單、易理解,存儲密度大,實際佔用最少的存儲空間。
  • 缺點:須要佔用一片地址連續的整塊空間,可能形成空間浪費。而且存儲分配要事先進行,插入、刪除效率低。

C 語言實現

書中介紹了順序表的幾種常見操做,本文嘗試用完整 C 語言實現。ui

頭文件與宏定義

編寫 util.h 頭文件,定義 ERRORMESSAGE,須要拋出異常時打印 log 並退出。在順序表的實現中,ElemTypeintspa

#include <stdio.h>
#include <stdlib.h>

#define ERRORMESSAGE(msg) \ { \ printf(msg); \ exit(1); \ }

typedef int ElemType;
複製代碼

順序表實現

編寫 02-list.c 文件,是順序表的實現文件。code

// 引入 util 頭文件
#include "util.h"
// 假設順序表最多存放 100 個數據元素
#define MaxSize 100

// 聲明順序表(使用數組實現)
ElemType A[MaxSize];
// 順序表實際存儲元素數量
int n = 0;
複製代碼

插入元素

書中的定義是第 i 個位置,下同,也就是說參數是從 1 開始的。順序表的插入操做時間複雜度爲 O(n)對象

/** * 在長度爲 n 的線性表 A 的第 i 個位置插入一個新數據元素 item */
void insertList(ElemType A[], int *n, int i, ElemType item) {
  if (*n == MaxSize || i < 1 || i > *n + 1) {
    ERRORMESSAGE("表滿或插入位置不正確!");
  }

  for (int j = *n - 1; j >= i - 1; j--) {
    A[j + 1] = A[j];
  }

  A[i - 1] = item;

  (*n)++;
}
複製代碼

刪除指定位置的元素

時間複雜度爲 O(n)string

/** * 刪除長度爲 n 的線性表 A 的第 i 個數據元素 */
void deleteList(ElemType A[], int *n, int i) {
  int j;
  if (i < 1 || i > *n) {
    ERRORMESSAGE("表滿或刪除位置不正確!");
  }

  for (j = i; j < *n; j++) {
    A[j - 1] = A[j];
  }

  (*n)--;
}
複製代碼

查找元素的位置

時間複雜度爲 O(n)it

/** * 肯定元素 item 在長度爲 n 的線性表 A 中的位置 */
int locate(ElemType A[], int n, ElemType item) {
  for (int i = 0; i < n; i++) {
    if (A[i] == item) {
      return i + 1;
    }
  }

  return -1;
}
複製代碼

刪除表中重複的元素

時間複雜度爲 O(n^2)io

/** * 刪除表中重複出現的元素 */
void purge(ElemType A[], int *n) {
  int i = 0, j;
  while (i < *n) {
    j = i + 1;

    while (j < *n) {
      if (A[j] == A[i]) {
        deleteList(A, n, j + 1);
      } else {
        j++;
      }
    }

    i++;
  }
}
複製代碼

查找並刪除元素

通常的實現方式是先遍歷查找,若是找到了進行刪除操做,時間複雜度爲 O(n^2)

優化版的時間複雜度爲 O(n),由於只須要記錄符合條件(須要被刪除)的個數,一遍遍歷便可完成操做。

/** * 基礎版 */
void deleteItem(ElemType A[], int *n, ElemType item) {
  int i = 0;
  while (i < *n) {
    if (A[i] == item) {
      deleteList(A, n, i + 1);
    } else {
      i++;
    }
  }
}

/** * 優化版 */
void deleteItem2(ElemType A[], int *n, ElemType item) {
  int k = 0;
  for (int i = 0; i < *n; i++) {
    if (A[i] == item) {
      k++;
    } else {
      A[i - k] = A[i];
    }
  }

  *n = *n - k;
}
複製代碼

打印數組

void printList(ElemType A[], int *n) {
  for (int i = 0; i < *n; i++) {
    printf("%d", A[i]);
  }

  printf("\n");
}
複製代碼
相關文章
相關標籤/搜索