1. 程式人生 > 其它 >有序表歸併演算法(資料結構學習筆記)

有序表歸併演算法(資料結構學習筆記)

技術標籤:資料結構學習筆記演算法資料結構連結串列

文章目錄


有序表歸併演算法

假設有兩個有序表LA和LB,設計一個演算法,將它們合併成一個有序表LC(假設每個有序表中和兩個有序表間均不存在重複元素),要求不破壞原有表LA和LB。

具體演算法思路:
用兩個變數i,j分別遍歷LA,LB,在遍歷過程中比較當前兩有序表中的最小值,並將最小值複製到有序表LC中。
最後直到其中一個有序表遍歷完畢,則預設另一個有序表中所有元素都大於遍歷完畢的有序表中的所有元素,就將另一個有序表中所有剩餘元素複製到有序表LC中。

具體圖解:

例如:LA=(1,3,5),LB=(2,4,8,10)

將變數i,j分別指向有序表LA和LB的第一個元素
在這裡插入圖片描述

對於當前變數i,j所指元素的最小值複製到有序表LC中,並將所選最小值的記錄變數i或j向後移動一位。
此時元素值最小的為變數i所指的元素(值為1),因此將變數i所指元素複製給有序表LC,並執行i++。
在這裡插入圖片描述

此時元素值最小的為變數j所指的元素(值為2),因此將變數j所指元素複製給有序表LC,並執行j++。
在這裡插入圖片描述

此時元素值最小的為變數i所指的元素(值為3),因此將變數i所指元素複製給有序表LC,並執行i++。
在這裡插入圖片描述

此時元素值最小的為變數j所指的元素(值為4),因此將變數j所指元素複製給有序表LC,並執行j++。

在這裡插入圖片描述

此時元素值最小的為變數i所指的元素(值為5),因此將變數i所指元素複製給有序表LC,並執行i++。
在這裡插入圖片描述

此時可以發現有序表LA已經遍歷完畢,而有序表LB還未遍歷完畢,因此可預設有序表LB中的所有剩餘元素都比有序表LA中的所有元素都大,因此可直接將有序表LB中的所有剩餘元素複製給有序表LC

在這裡插入圖片描述

很明顯可以看出此演算法的時間複雜度為O(m+n),空間複雜度為O(m+n)

順序表存放有序表的二路歸併演算法

程式碼:

#include <stdio.h>

typedef struct SqNode
{
	int data[30];
	int length;
}SqList;

SqList LA,
LB,LC; int NA,NB; //有序表LA,LB輸入函式 void ListInput() { LA.length=NA; LB.length=NB; for(int i=0;i<NA;i++) scanf("%d",&LA.data[i]); for(int i=0;i<NB;i++) scanf("%d",&LB.data[i]); } //二路歸併函式 void Union() { int i=0,j=0,k=0; while(i<LA.length&&j<LB.length){ if(LA.data[i]<LB.data[j]) LC.data[k++]=LA.data[i++]; else LC.data[k++]=LB.data[j++]; } while(i<LA.length) LC.data[k++]=LA.data[i++]; while(j<LB.length) LC.data[k++]=LB.data[j++]; LC.length=k; } //有序表輸出函式 void ListOutput() { for(int i=0;i<LC.length;i++) printf("%d ",LC.data[i]); } int main() { scanf("%d %d",&NA,&NB); ListInput(); Union(); ListOutput(); return 0; }

單鏈表存放有序表的二路歸併演算法

程式碼:

#include <stdio.h>
#include <stdlib.h>

typedef struct LNode
{
	int data;
	struct LNode *next;
}LinkNode;

int NA,NB;
LinkNode *LA,*LB,*LC;

//單鏈表輸入 
void ListInput()
{
	LinkNode *s,*ra,*rb;
	LA=(LinkNode *)malloc(sizeof(LinkNode));
	LA->next=NULL;
	ra=LA;
	
	LB=(LinkNode *)malloc(sizeof(LinkNode));
	LB->next=NULL;
	rb=LB;
	
	int a;
	for(int i=0;i<NA;i++){
		scanf("%d",&a);
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=a;
		s->next=ra->next;
		ra->next=s;
		ra=s;
	}
	
	for(int i=0;i<NB;i++){
		scanf("%d",&a);
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=a;
		s->next=rb->next;
		rb->next=s;
		rb=s;
	}
}

//二路並行演算法 
void Union()
{
	LinkNode *pa,*pb,*r,*s;
	LC=(LinkNode *)malloc(sizeof(LinkNode));
	r=LC;
	pa=LA->next;
	pb=LB->next;
	
	while(pa!=NULL&&pb!=NULL){
		if(pa->data<pb->data){
			s=(LinkNode *)malloc(sizeof(LinkNode));
			s->data=pa->data;
			r->next=s;
			r=s;
			pa=pa->next;
		}
		else{
			s=(LinkNode *)malloc(sizeof(LinkNode));
			s->data=pb->data;
			r->next=s;
			r=s;
			pb=pb->next;
		}
	} 
		
	while(pa!=NULL){
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=pa->data;
		r->next=s;
		r=s;
		pa=pa->next;
	}
	while(pb!=NULL){
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=pb->data;
		r->next=s;
		r=s;
		pb=pb->next;
	}
	//尾插法要在最後將尾節點的next域置為空 
	r->next=NULL;
}

//單鏈表輸出 
void ListOutput()
{
	LinkNode *p=LC->next;
	while(p!=NULL){
		printf("%d ",p->data);
		p=p->next;
	}
}

int main()
{
	scanf("%d %d",&NA,&NB);
	
	ListInput();
	
	Union();
	
	ListOutput();
	
	return 0;
}
  • 學習資料結構教程(第五版)——李春葆教授主編
  • 圖片來源於MOOC,資料結構——武漢大學——李春葆教授
  • (如若侵權可聯絡QQ刪除)