學習書籍《大話數據結構》,自學完後,總結一下,以後也好複習 ,歡迎互相交流。
線性表的基本操作功能如下:
InitList(*L): 初始化操作,建立一個空的線性表L
ListEmpty(L): 若線性表爲空,返回true,否則返回false
ClearList(*L): 將線性表清空
GetElem(L,i,*e) : 將線性表L中的第i個位置元素返回給e
LocateElem(L,e) : 在線性表L中查找與給定值e相等的元素,如果查找成功,返回該元素在表中序號表示成功;否則,返回0表示失敗
ListInsert(*L,i,e): 在線性表L中的第i個位置插入新元素e
ListDelete(*L,i,*e): 刪除線性表L中第i個位置元素,並用e返回其值
ListLength(L): 返回線性表L的元素個數
對於不同的應用,線性表的基本操作不同,對於現實中更復雜的操作,完全可以用這些基本操作完成。
例如:要實現兩個線性表集合的並,將結果存入集合C中。先將集合A插入集合C中,再循環B集合中的每個元素,判斷集合A中是否存在,不存在,則插入C。具體實現本代碼的void unionL(SqList *Lc, SqList Lb,SqList La);
要實現兩個線性表集合的交,將結果存入集合C中。分析略(和交集類似,就不寫了),具體實現本代碼void insertction(SqList La, SqList Lb, SqList *Lc);
代碼如下(編譯軟件vs2013):
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 30 /*存儲空間初始分配量*/
typedef int Status;/*status是函數的類型,其值是函數結果狀態代碼,如OK等*/
typedef int ElemType; /*ElemType類型根據實際情況而定,這裏假設爲int*/
//輸出元素c
Status visit(ElemType c)
{
printf("%d ", c);
return OK;
}
//線性表的順序存儲結構
typedef struct
{
ElemType data[MAXSIZE];//數組存儲數據元素,最大值爲MAXSIZE
int length; //線性表當前長度
}SqList;
//初始化順序線性表
Status InitList(SqList *L)
{
L->length = 0;
return OK;
}
/*初始條件:順序線性表L存在。操作結果:若L爲空表,則返回FALSE,否則返回TRUE*/
Status ListEmpty(SqList L)
{
if (L.length == 0)
return FALSE;
else
return TRUE;
}
//初始條件:順序線性表L已存在。操作結果:將L重置爲空表
Status ClearList(SqList *L)
{
L->length = 0;
return OK;
}
//初始條件:順序線性表L已存在。操作結果:返回線性表L元素個數
int ListLength(SqList L)
{
return L.length;
}
/*初始條件:順序線性表L已存在,1<=i<=ListLength(L)
操作結果:用e返回L中第i個數據元素的值,注意i是指位置,第1個位置的數組是從0開始*/
Status GetElem(SqList L, int i, ElemType *e)
{
if (L.length == 0 || i<1 || i>L.length)
return ERROR;
*e = L.data[i - 1];
return OK;
}
/*初始條件:順序線性表L已存在
操作結果:返回L中第1個與e滿足關係的數據元素的位序
若這樣的數據元素不存在,則返回值爲0*/
int LocateElem(SqList L, ElemType e)
{
int i;
if (L.length) //順序線性表L存在且不爲空
{
for (i = 0; i < L.length;i++)
if (L.data[i] == e)
return i+1;
}
return 0;
}
/*初始條件:順序線性表L已存在,1<=i<=ListLength(L)
操作結果:在L中第i個位置之前插入新的數據元素e,L中的長度加1*/
Status ListInsert(SqList *L, int i, ElemType e)
{
int k;
if (L->length == MAXSIZE || i < 1 || i>L->length + 1) //L滿或i小於1或大於最後一個位置+1
return ERROR;
else
{
if (i <= L->length)
{
for (k = L->length; k >= i; k--)
L->data[k] = L->data[k - 1];
}
L->data[i - 1] = e;
L->length++;
return OK;
}
}
/*初始條件:順序線性表L已存在,1<=i<=ListLength(L)
操作結果:刪除L的第i個元素,並用e返回其值,L的長度減1*/
Status ListDelete(SqList *L, int i, ElemType *e)
{
int k;
if (L->length == MAXSIZE || i < 1 || i>L->length) //L滿或i小於1或大於最後一個位置
return ERROR;
*e = L->data[i - 1]; //用e保存要刪除的元素
if (i<L->length)
for (k = i - 1; k < L->length-1; k++)
L->data[k] = L->data[k + 1];
L->length--;
return OK;
}
/*初始條件:順序線性表L已存在
操作結果:依次對L中的每個元素輸出*/
Status ListTraverse(SqList L)
{
int i;
for (i = 0; i < L.length; i++)
visit(L.data[i]);
printf("\n");
return OK;
}
//實現兩個線性表集合的並集操作
//將所有的線性表中元素不重複的存入Lc中
void unionL(SqList *Lc, SqList Lb,SqList La)
{
int La_len, Lb_len,Lc_len, i,j;
ElemType e; //聲明La與Lb相同的元素e
La_len = ListLength(La);
Lb_len = ListLength(Lb);
ClearList(Lc);
Lc_len = ListLength(*Lc);
for (j = 1; j <= La_len; j++)
{
GetElem(La, j, &e); //取La中第i個元素賦給e
ListInsert(Lc, ++Lc_len, e); //插入
}
for (i = 1; i <= Lb_len; i++)
{
GetElem(Lb, i, &e); //取Lb中第i個元素賦給e
if (!LocateElem(*Lc, e)) //La中不存在和e相同數據元素
ListInsert(Lc, ++Lc_len, e); //插入
}
}
//實現兩個集合的交集操作
//將所有的在線性表Lb中且在La中的數據元素插入到Lc中
void insertction(SqList La, SqList Lb, SqList *Lc)
{
int La_len, Lb_len, Lc_len, i;
ElemType e;
La_len = ListLength(La);
Lb_len = ListLength(Lb);
ClearList(Lc);
Lc_len = ListLength(*Lc);
for (i = 1; i <= Lb_len; i++)
{
GetElem(Lb, i, &e);
if (LocateElem(La,e)) //La中存在和e相同數據元素
ListInsert(Lc, ++Lc_len, e); //插入
}
}
int main()
{
SqList L;
ElemType e;
Status i;
int j, k;
i = InitList(&L);
printf("初始化L後:L.length=%d\n", L.length);
for (j = 0; j < 8; j++)
ListInsert(&L, 1, j);
printf("L表頭依次插入0--7:");
ListTraverse(L);
printf("L是否爲空:(1否0是)%d\n", ListEmpty(L));
ClearList(&L);
printf("清空線性表L\n");
printf("L是否爲空:(1否0是)%d\n", ListEmpty(L));
for (int j = 1; j <=10; j++)
{
ListInsert(&L, j, j-1);
}
printf("在L表中1--10位置輸入0--9數字:");
ListTraverse(L);
GetElem(L, 3, &e);
printf("輸出L中第3個元素:%d\n",e );
k = LocateElem(L, 3);
if (k)
printf("找出L中第一個3所在的位置:%d\n",k);
else
{
printf("L中無此元素\n");
}
k = ListDelete(&L, 4, &e);
if (k)
printf("刪除L中第4個元素值爲: %d\n", e);
else
printf("刪除失敗\n");
printf("輸出L中所有的元素:");
ListTraverse(L);;
SqList Lb;
SqList Lc;
InitList(&Lc);
InitList(&Lb);
for (j = 0; j < 7; j++)
{
ListInsert(&Lb, j, j + 5);
}
printf("輸出Lb中所有的元素:");
ListTraverse(Lb);
unionL(&Lc,L, Lb);
printf("輸出L和Lb標的並集:");
ListTraverse(Lc);
insertction(L, Lb, &Lc);
printf("輸出L和Lb標的交集:");
ListTraverse(Lc);
system("pause");
return 0;
}
結果截圖:
插入和刪除的平均時間複雜度:O(n)
線性表順序存儲結構的優缺點:
優點: 1.無須爲表示表中元素之間的邏輯關係而增加額外的存儲空間
2.可以快速地存取表中任一位置的元素
缺點: 1.插入和刪除操作需要移動大量元素
2.當線性表長度變化較大時,難以確定存儲空間的容量
3.造成存儲空間的“碎片”