浙江中醫藥大學-《資料結構》(C語言版)-第一章-第二章概念與程式碼
ZCMU-Data Structure(C language)
Part 1 Exordium
1、Data:能夠輸入到計算機中並被計算機程式處理的符號的總稱。
2、Data Element:資料的基本單位,資料元素用以完整的描述一個物件。
3、Data Item:組成資料元素、有獨立含義、不可分割的最小單位。
4、Data Object:性質相同的資料元素的集合。
5、資料結構的三要素:資料邏輯結構、資料儲存結構、資料運算:
其中:資料的邏輯結構包含
資料的儲存結構(物理結構)包含:順序儲存結構、鏈式儲存結構。
6、演算法的五個特性:
1)有窮性
2)確定性
3
4)輸入
5)輸出
7、演算法評價標準:
1)正確性
2)可讀性
3)健壯性
4)高效性
8、演算法複雜性分析:定義1.1 在計算演算法時間複雜度時,可以忽略所有低次冪項和最高次冪項的係數,簡化演算法分析,體現增長率的含義。(例項見《資料結構 C語言版》嚴蔚敏 P13-P14 P17習題6)
Part 2 Linear List
9、對於非空的線性表或線性結構,包含以下特點:
1)存在唯一的一個被稱作“第一個”的資料元素。
2)存在唯一的一個被稱作“最後一個”的資料元素。
3)除第一個之外,結構中的每個資料元素均只有一個前驅。
4)除最後一個之外,結構中的每個資料元素只有一個後繼。
10、線性表應用例項:稀疏多項式運算、圖書管理系統。
11、線性表的順序表示(順序儲存結構)指的是用一組地址連續的儲存單元依次儲存線性表的資料元素,特點是:邏輯上相鄰的資料元素、物理次序也相鄰;因此只要確定了儲存線性表的起始位置,線性表中任一資料元素都可以隨機儲存,所以線性表的順序儲存結構是一種隨機儲存的儲存結構。
12、順序表中基本操作的實現:
1)初始化
為順序表動態分配一個預定大小的陣列空間,使elem指向這段空間的基地址。
Status InitList(Sqlist &L) { L.elem=new ElemType[MAXSIZE]; if(!L.elem) exit(OVERFLOW); L.length=0; return OK; }
2)取值
由於順序儲存結構具有隨機儲存的特點,可以直接通過陣列下標定位得到。elem[i-1]儲存第i個數據元素。
if(i<1||i>L.length)return ERROR; //判斷i是否合理
e=L.elem[i-1];
return OK;
3)查詢
從第一個元素起,依次和e比較,若找到與e相等的元素L.elem[i],則查詢成功,返回該元素的序號i+1。
for(i=0;i<L.length;i++)
if(L.elem[i]==e) return i+1;
return 0;
順序表查詢平均時間複雜度為O(n)。
4)插入
一般情況下,在第i個位置插入一個元素時,需要從最後一個元素即第n個元素開始,依次向後移動一個位置,直至第i個元素(共n-i+1個元素)。
if((i<1)||(i>L.length+1) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //當前儲存空間已滿
for(j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j];//插入位置之後元素後移
L.elem[i-1]=e;//將新元素e放入第i個位置
++L.length;//表長+1
順序表插入演算法的平均時間複雜度為O(n)。
5)刪除
一般情況下,刪除第i個元素需要將第i+1個元素至第n個元素(共n-i)個元素依次向前移動一個位置(i=n時無需移動)。
if((i<1)||(i>L.length)) return ERROR ;
for(j=i;j<=L.lenrth-1;j++)
L.elem[j-1]=L.elem[j];//前移
--L.length;
return OK;
順序表刪除演算法平均時間複雜度為O(n)。
13、線性錶鏈式儲存的特點:用一組任意的儲存單元儲存線性表內的資料元素,這組儲存單元可以是連續的,也可以是不連續的,因此需要包含兩個部分,一是資料本身,二是結點,結點包含兩個域,儲存資料元素資訊的為資料域,儲存直接後繼位置的域成為指標域,連結串列中的每個結點只包含一個指標域。同時由於最後一個數據元素沒有直接後繼,單鏈表中最後一個結點的指標為空。
14、連結串列增加頭結點的作用:
1)便於首元結點的處理
2)便於空表和非空表的統一處理
15、單鏈表是非隨機存取的儲存結構,要取得第i個數據元素必須從頭指標出發順鏈進行尋找,稱為順序存取的儲存結構。
16、單鏈表的基本操作的實現
1)初始化
L=new LNode;//生成新結點作為頭結點
L->next=NULL;
return OK;
2)取值
//在帶頭結點的單鏈表L中根據序號i獲取元素的值,用e返回第i個數據元素的值
p=L->next;j=1;//p指向首元結點,計數器j為1
while(p&&j<i)//順鏈域向後掃描,直到p為空域或p指向第i個元素
{
p=p->next;//指向下一個結點
++j;
}
if(!p||j>i) return ERROR;
e=p->data; //取第i個結點的資料域
return OK;
單鏈表取值平均時間複雜度為O(n)。
3)查詢
p=L->next; //初始化,p指向首元結點
while(p&&p->data!=e)
p=p->next;
return p;
單鏈表查詢平均時間複雜度為O(n)。
4)插入
p=L;j=0;
while(p&&(j<i-1))
{p=p->next;++j; }//查詢第i-1個結點,p指向該結點
if(!p||j>i-1) return ERROR;
//重點
s=new LNode;
s->data=e;
s->next=p->next;
p->next=s;
return OK;
5)刪除
p=L;j=0;
while((p->next)&&(j<i-1))
{p=p->next;++j;}
if(!(p->next)||(j>i-1)) return ERROR;
//重點
q=p->next;
p->next=q->next;//改變刪除結點前驅結點的指標域
delete q;
return OK:
插入和刪除演算法平均時間複雜度均為O(n)。
17、實現前插法和後插法建立單鏈表完整程式碼
#include<stdio.h>
#include<stdlib.h>
typedef int Elem;
typedef struct Node
{
Elem data;
struct Node *next;
}Node,*LinkList;
LinkList LinkListBegin()
{
Node *L;
L=(Node *)malloc(sizeof(Node));
if(L=NULL)
printf("Fall");
L->next=NULL;
}
///扦插
LinkList LinkListqiancha()
{
Node *L;
L=(Node *)malloc(sizeof(Node));
L->next=NULL;
Elem x;
while(scanf("%d",&x)!=EOF)
{
Node *p;
p=(Node *)malloc(sizeof(Node));
p->data=x;
p->next=L->next;
L->next=p;
}
return L;
}
//後插
LinkList LinkListhoucha()
{
Node *L;
L=(Node *)malloc(sizeof(Node));
L->next=NULL;
Node *r;
r=L;
Elem x;
while(scanf("%d",&x)!=EOF)
{
Node *p;
p=(Node *)malloc(sizeof(Node));
p->data=x;
r->next=p;
r=p;
}
r->next=NULL;
return L;
}
//charu
LinkList LinkListInsert(LinkList L,int i,Elem x)
{
Node *pre;
pre=L;
int temp=0;
for(temp=1;temp<i;temp++)
pre=pre->next;
Node *p;
p=(Node *)malloc(sizeof(Node));
p->data=x;
p->next=pre->next;
pre->next=p;
return L;
}
//
LinkList LinkListDelete(LinkList L, Elem x)
{
Node *p,*pre;
p=L->next;
while(p->data!=x)
{
pre=p;
p=p->next;
}
pre->next=p->next;
delete(p);
return L;
}
int main()
{
LinkList list,start;
list=LinkListqiancha();
for(start=list->next;start!=NULL;start=start->next)
printf("%d",start->data);
int i;
scanf("%d",&i);
Elem x;
scanf("%d",&x);
LinkListInsert(list,i,x);
for(start=list->next;start!=NULL;start=start->next)
printf("%d",start->data);
scanf("%d",&x);
LinkListDelete(list,x);
for(start=list->next;start!=NULL;start=start->next)
printf("%d",start->data);
}
18、迴圈連結串列、連結串列合併
迴圈連結串列的特點是表中最後一個結點的指標域指向頭結點,整個連結串列形成一個環。
迴圈連結串列和單鏈表判斷指標p是否指向表尾的終止條件不同:
單鏈表:p!=NULL或p->next!=NULL
迴圈連結串列:p!=L或p->next!=L
連結串列合併僅需將第一個表的尾指標指向第二表的第一個結點,第二個表的尾指標指向第一個表的頭結點,然後釋放第二個表的頭結點,實現程式碼:
p=B->next->next;
B->next=A->next;
A->next=p;
19、儲存密度=資料元素本身佔用的儲存量/結點結構佔用的儲存量
順序表的儲存密度為1,連結串列儲存密度小於1,若不考慮順序表中的空閒區,順序表儲存空間利用率100%,單鏈表儲存空間利用率50%。
20、主要操作是和元素位置緊密相關的這類取值操作,採用順序表;對於頻繁進行插入或刪除的線性表,採用連結串列。