線性表--大體知識點

一、線性表的定義

線性表:零個或多個數據元素的有限序列

  1. 元素之間是有順序的。
  2. 第一個元素無前驅,最後一個元素無後驅,其他的每一個元素有且只有一個前驅和後驅。
  3. 線性表元素的個數n定義爲線性表的長度,n=0,空表。

二、線性表的抽象數據類型

線性表的抽象數據類型定義如下:

/****抽象數據類型定義******/
InitList(*L);       //初始化操作,建立一個空的線性表L
ListEmpty(L);       //若線性表爲空,返回true,否則返回false
ClearList(*L);      //將線性表清空
GetElem(L,i,*e);    //將線性表L中的第i個元素值返回給e
LocateElem(L,e);    //查找成功放回序號,查找失敗返回0
ListInsert(*L,i,e)  //在線性表L的第i個位置插入e
ListDelet(*L,i,*e)  //刪除第i個位置元素,並用e返回其值
ListLength(L);      //返回線性表的元素個數 

三、線性表的順序存儲結構

1.順序存儲定義:用一段地址連續的存儲單元依次存儲線性表的數據元素。
2.順序存儲方式:C語言的一維數組

/*********順序存儲的結構代碼**********/
#define MAXSIZE 20    //存儲空間初始分配量
typedef int ElemType;
typedef struct
{
	ElemType data[MAXSIZE];
	int length;
 } SqList;
 

順序存儲結構需要三個屬性:

  • 存儲空間的起始位置:數組data
  • 線性表的最大存儲容量:數組長度MAXSIZE
  • 線性表的當前長度:length3.

3.數據長度與線性表長度

  • 數據長度:存儲的空間長度(MAXSIZE)
  • 線性表長度:元素個數(length)

4.地址的計算辦法
存儲器中的每個存儲單元都有自己的編號,這個編號稱爲地址。

四、順序存儲結構的插入與刪除

  1. 獲得元素操作
  2. 插入操作
  3. 刪除操作
 /**********獲得元素的操作******************/
 #define OK 1
 #define ERROR 0
 Statues 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;
		
}
/***************順序存儲結構的插入**********************/
Status ListInsert(SqList *L,int i,ElemType)
{
	int k;
	if(L->length>MAXSIZE)      //線性表已滿 
		return ERROR;
	if( i<1 || i>L->length )   //i的位置不對
		return ERROR;
	if( i <= L->length)
	{
		for(k=L->length-1; k>=i-1; k--)   //將插入位置後的元素向後移動一位
		{
			L->data[k+1] = L->data[k];
		}	
	} 
	L->data[i-1]=e;
	L->length++;
 } 
 /******************順序存儲結構的刪除*************/
 Status ListDelete(SqList *L,int i, ElemType)
 {
 	int k;
 	if(L->length==0)     //線性表爲空
	 	return ERROR;
	if( i<1 || i>L->length )   //i的位置不對
		return ERROR; 
	*e = L->data[i-1] 
	if( i <= L->length)
	{
		for(k=i; k<L->length; k--)   //將插入位置後的元素向後移動一位
		{
			L->data[k-1] = L->data[k];
		}	
	} 
	return OK;
  } 

五、線性表的鏈式存儲結構

  1. 順序存儲結構的不足:插入和刪除時需要移動大量的元素
  2. 線性表的鏈式存儲結構的定義
    結點:
    鏈表:n個結點鏈結成一個鏈表
    單鏈表:鏈表中的每個結點只包含一個指針域
    頭指針:鏈表中的第一個結點的存儲位置
    頭結點:在單鏈表的第一個結點前附設一個結點,稱爲頭結點
  3. 頭指針和頭結點的異同
    頭指針:指向鏈表第一個結點的指針,若鏈表有頭結點,則是指向頭結點的指針。頭指針是鏈表的必要的元素
    頭結點:放在第一個元素之前的結點,頭結點不是鏈表的必須要素
  4. 線性錶鏈式存儲結構代碼描述
/***************線性表的單鏈表存儲結構*****************/
typedef struct Node
{
	ElemType data;
	struct Node *next;
 } Node;
 typedef struct Node *LinkList; 

鏈接由結點構成
結點由存放數據的元素的數據域和存放後繼結點地址的指針域組成

六、單鏈表的讀取

獲取單鏈表的第i個數據

  1. 聲明一個指針p指向單鏈表的第一給結點 j=1;
  2. j<i時,遍歷鏈表,讓p指針向後移動,不斷的指向下一個結點,j++;
  3. 若到單鏈表的尾部,則說明i 點不存在;
  4. 否則查找成功,返回結點p的數據、
 Status GetElem(LinkList L,int i,ElemType *e)
 {
 	int j;
 	LinkList p;     //聲明一個指針p
	p = L->next;    //p指向鏈表L的第一個結點 
	j = 1;
	while( p && j<i )  //p不爲空 且 j<i 
	{
		p = p->next;
		j++;
	 }
	if(!p || j>i)
	 	return -1;
		 
	*e = p->data;
	return 0; 
 }

七、單鏈表的插入與刪除

  1. 單鏈表的插入
    先把p的後繼結點改成s的後繼結點
    在把s變成p的後繼結點
    (順序不可以變)
 
 /**********************單鏈表的插入(單鏈表第i個數據插入結點)*************************/
 /*
 	 1.聲明一指針p指向鏈表的頭結點,同時 j = 1 
	 2.當 j < i 時,遍歷鏈表,讓p指針向後移動,不斷指向下一個結點, p++
	 3.若到鏈表的末尾p爲空,則說明第i個結點不存在
	 4.否則查找成功,在系統中生成一個空節點s
	 5.將元素e賦值給s->data
	 6.單鏈表的插入標準語句 s->next = p->next       p->next = s
	 7.返回成功
*/
Status ListInsert(LinkList *L,int i,ElemType e) 
{
	int j;
	LinkList p,s;
	p = *L;     //指針指向鏈表l 
	j = 1;
	while( p && j < i )
	{
		p = p->next;
		j++;
	}
	if(!P || j < i)
		return -1;
	s = (LinkList)malloc(sizeof(Node)) ;     //生成新結點 
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 0;	
}
  1. 單鏈表的刪除
    只需要一步:p->next = p->next->next
/******************單鏈表的刪除***************/
/*	
	1.聲明一個指針p指向鏈表頭指針, j = 1
	2.當 i < j時,就遍歷鏈表,讓p指針向後移動,不斷的指向下一個結點, j++
	3.若到鏈表尾部p爲空,則說明i結點不存在
	4.否則查找成功,將欲刪除的結點 p->next賦值給q
	5.單鏈表的刪除標準語句 p->next = q->next
	6.將q結點中的數據賦值給e,作爲返回
	7.釋放q結點
	8.返回成功
*/

Status ListDelete(LinkList *L,int i,ElemType e)
{
	int j;
	LinkList p,q;
	j = 1;
	while(p->next && j < i)
	{
		p = p->next;
		j++;
	 } 
	 if( !(p->next) || j > i )
	 	return -1;
	 	
	q = p->next;
	p->next = q->next;
	*e = q->data;
	free(q);    //釋放結點q
	return 0; 
}
	 

八、單鏈表整表的建立

單鏈表的建立就是一個動態生成鏈表的過程;從‘空表‘的初始狀態起,依次建立各元素結點,並逐個插入鏈表。
單鏈表整表的建立有兩種方法:頭插法,尾插法

/*********單鏈表整表創建的算法:頭插法********************/
/*
	1.聲明一個 指針p 和 計數變量 i;
	2.初始化一個空鏈表L;
	3.讓L的頭結點的指針指向空,即建立一個帶頭結點的單鏈表; 
	4.循環:
		生產一個新節點賦值給p; 
		生成一個新節點賦值給p的數據域 p->data;
		將p插入到頭結點與前一個新結點之間;
		
*/
void CreatListHead(LinkList *L,int n)
{
	LinkList p;      //聲明指針 p
	int i;
	srand(time(0));
	*L = (LinkList)malloc(sizeof(Node));  
	(*L)->next = NULL;           //創建一個帶頭結點的鏈表L
	
	for( i = 0; i < n; i++)
	{
		p = (LinkList) malloc (sizeof(Node));   //生成新結點
		p->data = rand()%100 + 1;
		p->next = (*L)->next;   //查入到表頭 
	 } 
	
}
/*********單鏈表整表創建的算法:尾插法********************/
void CreatListTail(LinkList *L,int n)
{
	LinkList p,r;;
	int i;
	srand(time(0));
	*L = (LinkList)malloc(sizeof(Node));   //爲整個線性表
	r = L;
	for( i = 0; i < n; i++)
	{
		p = (Node *)malloc(sizeof(Node));    //生成新結點
		p->data = rand()%100+1;
		r->next = p;    //將表尾終端結點的指針指向新結點 
		r = p;          //新結點變成尾結點 
	 } 
	 r->next = NULL;    //表示當前鏈表結束 
 } 

九、單鏈表整表的刪除


/*********************單鏈表的刪除 ************************/
/*
	1.聲明一個結點p和q;
	2.將第一個結點賦值給p;
	3.循環:
		將下一個結點賦值給q;
		釋放p;
		將q賦值給p;
*/
Status ClearList(LinkList *L)
{
	LinkList p,q;
	p = (*L)->next;    //p指向第一個結點
	while(p)           //沒到表尾 
	{
		q = p->next;
		free(q);
		p = q;
	 } 
	 (*L)->next =NULL;
	 return 0;
 } 

十、靜態鏈表

  1. 定義:用數組描述的鏈表叫做靜態鏈表
  2. 數組元素都是由兩個數據域組成的,data和cur.
    data:用來存放數據元素
    cur:相當於單鏈表中的next,存放元素的後繼在數組中的下標,稱作遊標
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章