線性表的相關算法總結

順序表的操作

1. 順序表的存儲結構定義

#define MAXSIZE 100
typedef int ElemType;

typedef struct
{
	ElemType *elem;		//存儲空間基址
	int length;			//表長
}SqList;

2. 初始化順序表

void InitList_Sq(SqList &L)
{
	//構造一個空的順序表L。
	L.elem = new ElemType[MAXSIZE];
	if(!L.elem)
		exit(OVERFLOW); 	// 存儲分配失敗
	L.length = 0;			// 空表長度爲0
}

3. 銷燬順序表

void DestroyList(SqList &L)
{
	if(L.elem)
		delete(L.elem);		//釋放存儲空間
	L.length = 0;
	L.elem = NULL;
}

4. 清空順序表

void ClearList(SqList &L)
{
	L.length = 0;		//將線性表的長度置爲0
}

5. 求順序表的長度

int GetLength(SqList L)
{
	return L.length;
}

6. 判斷順序表是否爲空

bool IsEmpty(SqList L)
{
	if(L.length == 0)
		return true;
	else
		return false;
}

7. 獲取順序表中的某個位置數據元素內容

時間複雜度爲O(1)

void GetElem(SqList L,int i,ElemType &e)
{
	if(i<1 || i>L.length)	//判斷i值是否合理,若不合理,返回ERROR
		return ERROR;
	e = L.elem[i-1];     //i是元素在表中的位置
}

8. 在順序表中查找值爲e的數據元素

時間複雜度爲O(n)

int LocateElem(SqList L,ElemType e)
{
	for(int i=0;i<L.length;i++)
		if(L.elem[i] == e)
			return i+1;		//i是存儲單元的位置
	return 0;
}

9. 在順序表中插入一個數據元素

時間複雜度爲O(n)

void ListInsert_Sq(SqList &L,int i,ElemType e)
{
	if(i<1 || i>L.length+1)		//判斷插入位置是否合法
		return ERROR;
	if(L.length == MAXSIZE) 	//當前存儲空間是否已滿
		return ERROR;
	for(int j = L.length-1;j>=i-1;j--)		//將元素後移
		L.elem[j+1] = L.elem[j];
	L.elem[i-1] = e;
	++L.length;
}

10. 刪除順序表中的第i個數據元素

時間複雜度爲O(n)

void ListDelete_Sq(SqList &L,int i)
{
	if(i<1 || i>L.length)		//判斷插入位置是否合法
		return ERROR;
	for(int j=i-1;j<L.length;j++)		//將元素前移
		L.elem[j] = L.elem[j+1];
	--L.lehgth;
}

鏈表的操作

1. 單鏈表的存儲結構定義

typedef struct LNode
{
	ElemType data;			//數據域
	struct LNnode *next;	//指針域
}LNode,*LinkList;			//LinkList爲LNode類型的指針

2. 初始化單鏈表

void InitList_L(LinkList &L)
{
	L = new LNode;
	L->next = NULL;
}

3. 銷燬單鏈表

void DestroyList_L(LinkList &L)
{
	LinkList p;
	while(p)
	{
		p = L;
		L = L->next;
		delete p;
	}
}

4. 清空單鏈表

void ClearList(LinkList &L)
{
	LinkList p,q;
	p = L->next;
	while(p)			//沒到表尾 
	{
		q = p->next;	//p指向第一個結點
		delete p;
		p = q;
	}
	L->next = NULL;		//頭結點指針域爲空 
}

5. 求單鏈表的長度

int ListLength_L(LinkList L)
{
	LinkList p;
	p = L->next;
	count = 0;
	//遍歷單鏈表,統計結點數
	while(p)
	{
		++count;
		p = p->next;
	}
	return count;
}

6. 判斷單鏈表是否爲空

bool ListEmpty(LinkList L)
{
	if(L->next)
		return true;
	else
		return false;
}

7. 獲取單鏈表中的某個數據元素內容

時間複雜度爲O(n)

//獲取第i個位置的元素
void GetElem_L(LinkList L,int i,ElemType &e)
{
	LinkList p = L->next;
	int j = 1; 
	//向後掃描,直到p指向第i個元素或p爲空 
	while(p && j<i)
	{
		p = p->next;
		++j;
	}
	if(!p || j>i)			//第i個元素不存在 
		return ERROR;
	e = p->data;			//取第i個元素 
}

8. 檢索值爲e的數據元素

LNode *LocateElem_L(LinkList L,ElemType e)
{
	p = L->next;
	while(p && p->data != e)
		p = p->next;
	//返回L中值爲e的數據元素的位置,查找失敗返回NULL 
	return p;				
}

9. 在單鏈表中插入一個數據元素

時間複雜度爲O(1)

void ListInsert_L(LinkList L,int i,ElemType e)
{
	p = L;
	j = 0;
	//尋找第i−1個結點 
	while(p && j<i-1)
	{
		p = p->next;
		++j;
	}
	//i大於表長 + 1或者小於1  
	if(!p || j>i-1)
		return ERROR;
	//生成新結點*s 
	s = new LNode;
	s->data = e;           //將結點*s的數據域置爲e 
	s->next = p->next;	   //將結點*s插入L中 
	p->next = s;
}

10. 刪除單鏈表中第i個數據

時間複雜度爲O(1)

void ListDelete_L(LinkList L,int i,ElemType &e)
{
	p = L;
	j = 0;
	//尋找第i個結點,並令p指向其前驅 
	while(p->next && j<i-1)
	{
		p = p->next;
		++j;
	}
	//刪除位置不合理 
	if(!p->next || j>i-1)
		return ERROR;
	//臨時保存被刪結點的地址以備釋放 
	r = p->next;
	//改變刪除結點前驅結點的指針域 
	p->next = r->next;
	e = r->data;
	//釋放結點 
	delete r;
}

11. 單鏈表的建立

//前插法
void CreateList_H(LinkList &L,int n)
{
	L = new LNode;
	L->next = NULL;			//先建立一個帶頭結點的單鏈表 
	for(int i=n;i>0;i--)
	{
		p = new LNode;		//生成新結點 
		cin >> p->data;
		p->next = L->next;
		L->next = p;		//插入到表頭 
	}
}
//後插法
//正位序輸入n個元素的值,建立帶表頭結點的單鏈表L 
void GreateList_R(LinkList &L,int n)
{
	L = new LNode;
	L->next = NULL;
	r = L;				//尾指針r指向頭結點 
	for(int i=0;i<n;i++)
	{
		p = new LNode;	//生成新結點 
		cin >> p->data;
		p->next = NULL;
		r->next = p;		//插入到表尾 
		r = p;				//r指向新的尾結點 
	}
}

線性表的應用

1. 線性表的合併

void union(List &La,List &Lb)
{
	La_len = ListLength(La);		//線性表La的長度
	Lb_len = ListLength(Lb);		//線性表Lb的長度
	for(int i=1;i<=La_length;i++)
	{
		GetElem(Lb,i,e);			// 取Lb中第i個數據元素賦給e
		// La中不存在和 e 相同的數據元素,則插入之
		if(!LocateElem(La,e))
			ListInsert(La,++La_len,e);
	}
}

2. 鏈式有序表的合併

//按值排序的單鏈表LA,LB,歸併爲LC後也按值排序
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{
	//初始化  
	pa = La->next;
	pb = Lb->next;
	Lc = pc = La;
	//將pa 、pb結點按大小依次插入C中
	while(pa && pb)
	{
		if(pa->data <= pb->data)
		{
			pc->next = pa;
			pc = pa;
			pa = pa->next;
		}
		else
		{
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
	//插入剩餘段
	pc->next = pa?pa:pb;
	//釋放Lb的頭結點
	delete pb;
}

3. 順序有序表的合併

void MergeList(List La,List Lb,List &Lc)
{
	InitList(Lc);
	i = j = 1;
	k = 0;
	La_len = ListLength(La);
	La_len = ListLength(La);
	while(i<=La_len)&&(j<=Lb_len)
	{   	
		GetElem(La,i,ai); 
		GetElem(Lb,j,bj);
		if (ai<=bj)
		{
			ListInsert(Lc,++k,ai);
			++i;
		}
		else
		{
            ListInsert(Lc,++k,bj);
            ++j;
        }
     }
     while (i<=La_len)
     {
     	GetElem(La,i++,ai);
     	ListInsert(Lc,++k,ai);
     }
     while (j<=Lb_len)
     {
     	GetElem(Lb,j++,bj);
     	ListInsert(Lc,++k,bj);
     } 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章