一、基本概念:
線性表:由n個類型相同的數據元素組成的有限序列,記爲(a1,a2,……an)。
線性表的特徵:其中的元素存在這序偶關係,元素之間存在着嚴格的次序關係。
順序存儲表:線性表中的元素依次存放在一組地址連續的存儲單元(數組)中。
存儲特點:若已知首元素的起始地址a0和每個元素佔用的空間m,則計算第i個元素的存儲位置:ai = a0 + (i - 1)m。
順序表的特徵:(1)在邏輯上相鄰的元素,在物理上也是相鄰
(2)知道表中起始元素的地址,線性表中的任一個元素地址都可以確定,因此很容易實現對線性表中的元素的隨機訪問。
動態順序表:動態存儲分配方式實現
二、代碼實現:
1)結構實現(行號是爲了閱讀和說明代碼方便,請複製代碼是忽略行號)
typedef int ElemType; //定義一種數據類型
#define INITSIZE 60 //定義一個動態表的初始化大小的值
typedef struct{ //封裝了數據類型
ElemType *data;
int len;
int listSiz;
} SqList;
2)抽象數據類型(主要是爲了說明定義的結構(本例中是順序表)支持的運算操作,爲了使用上的方便,建議使用頭文件加實現的方式來運用,引入了bool變量,包含頭文件stdbool.h)
void listInit(SqList *L); //表的初始化
bool listEmpty(SqList L); //判斷表是否爲空
bool listFull(SqList L); //判斷表是否已滿
void listCreate(SqList *L); //創建表
void listPrint(SqList L); //輸出表的內容
void listDestroy(SqList *L); //表的銷燬,涉及內存分配,因此必須free
void listInsert(SqList *L, int i, ElemType e); //在表中i的位置插入元素e
int listLength(SqList L); //獲取表的長度
int listSerch(SqList L, ElemType e); //在表中查找元素e,返回其在表中的位置
ElemType listDelete(SqList *L, int i); //刪除表中位置爲i的元素,並返回刪除元素的值
ElemType listVisit(SqList L, int i); //訪問表中第i個元素,並返回元素的值
3)頭文件實現
將1)和2)中的代碼整合後,在第4行加上#ifndef SqList_H,在第42行加上#endif,實際項目中這樣作是爲了避免重複定義和引用頭文件,文件名爲SqList.h,完整代碼如下:
#include <stdbool.h>
typedef int ElemType;
#ifndef SqList_H
#define SqList_H
#define INITSIZE 60
typedef struct{
ElemType *data;
int len;
int listSiz;
} SqList;
void listInit(SqList *L); //表的初始化
bool listEmpty(SqList L); //判斷表是否爲空
bool listFull(SqList L); //判斷表是否已滿
void listCreate(SqList *L); //創建表
void listPrint(SqList L); //輸出表的內容
void listDestroy(SqList *L); //表的銷燬,涉及內存分配,因此必須free
void listInsert(SqList *L, int i, ElemType e); //在表中i的位置插入元素e
int listLength(SqList L); //獲取表的長度
int listSerch(SqList L, ElemType e); //在表中查找元素e,返回其在表中的位置
ElemType listDelete(SqList *L, int i); //刪除表中位置爲i的元素,並返回刪除元素的值
ElemType listVisit(SqList L, int i); //訪問表中第i個元素,並返回元素的值
#endif
4)操作算法實現,實現頭文件定義的順序表的操作,文件名爲SqList.c(注意頭文件和和實現文件名字一模一樣,只有後綴名由區別),具體代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include "SqList.h"
void listInit(SqList *L){
(*L).data = (ElemType *)malloc(sizeof(ElemType) * INITSIZE);
if(0 == (*L).data){
return;
}
(*L).len = 0;
(*L).listSize = INITSIZE;
}
bool listEmpty(SqList L){
return (0 == L.len);
}
bool listFull(SqList L){
return (listSize == L.len);
}
void listCreate(SqList *L){
printf("please input the lenth of list:");
scanf("%d", &((*L).len));
if((*L).len > (*L).listSize){
(*L).listSize = (*L).len + INITSIZE / 2;
free((*L).data);
(*L).data = (ElemType *)malloc(sizeof(ElemType) * (*L).listSize);
if(0 == (*L).data){
return;
}
}
for(int i = 0; i <= (*L).len; i++){
printf("please input NO%d element: ", i);
scanf("%d", &((*L).data[i]));
}
return;
}
void listPrint(SqList L){
for(int i = 0; i < L.len; i++){
printf("%d\t", L.data[i]);
}
printf("\n");
return;
}
void listDestroy(SqList *L){
free((*L).data);
(*L).data = NULL;
(*L).len = 0;
(*L).listSize = 0;
return;
}
void listInsert(SqList *L, int i, ElemType e){
if(i < 0 || i > (*L).len){
return;
}
if(listFull(*L)){
(*L).listSize = (*L).listSize + INITSIZE / 2;
(*L).data = (ElemType *)realloc(sizeof(ElemType) * (*L).listSize);
if(0 == (*L).data){
return;
}
}
for(int j = (*L).len - 1; j >= i - 1; j--){
(*L).data[j + 1] = (*L).data[j];
}
(*L).data[i - 1] = e;
(*L).len++;
return;
}
int listLength(SqList L){
return L.len;
}
int listSerch(SqList L, ElemType e){
for(int i = 0; i < L.len; i++){
if(e == L.data[i]){
return i;
}
}
return -1;
}
int listDelete(SqList *L, int i){
if(i < 0 || i > (*L).len){
return -1;
}
if(listEmpty(*L)){
return -2;
}
ElemType e = (*L).data[i - 1];
for(int j = i; j < (*L).len; j++){
(*L).data[j - 1] = (*L).data[j]
}
(*L).len--;