顺序表A和B的合并与排序

Posted sanqima

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了顺序表A和B的合并与排序相关的知识,希望对你有一定的参考价值。

用顺序表A和B表示的两个线性表,元素的个数分别是m和n, 若表中数据都是从小到大顺序排列的,且这(m+n)个数据中没有重复的。
  (1) 设计一个算法将此两个线性表合并成一个,仍是数据由小到大排列的线性表,存储到另一个顺序表C中。
  (2) 如果顺序表B的大小为(m+n)个单元,是否可不利用顺序表C而将合成的线性表存放于顺序表B中? 试设计算法。
  (3) 设顺序表A有m+n个元素,且前m个元素,后n个元素有序,设计一个算法,使得整个顺序表有序。
  解答:
  1)用 i i i j j j分别扫描顺序表 A A A B B B, 比较它们的当前元素,将较小者复制到顺序表 C C C中,这一过程循环到其中一个顺序表扫描完毕为止。将另一个顺序表余下的元素全部复制到顺序表C中。算法如下:

void meger1(SqList *&A, SqList *&B, SqList *&C)
	int i=0,j=0,k=0; //i扫描A,j扫描B
	while(i< A->length && j< B->length)
	
		if (A->data[i] < B->data[j])
		
			C->data[k] = A->data[i];
			i++; k++;
		 
		else
		
			C->data[k] = B->data[j];
			j++; k++;
		
	
	
	while(i< A->length) //若A未扫描完,则将A剩余的元素加到C中
		C->data[k] =A->data[i];
		i++; k++;
	

	while(j< B->length) //若B未扫描完,则将B剩余的元素加到C中
		C->data[k] = B->data[j];
		j++; k++;
	
	C->length=k;

本算法的时间复杂度为 O ( m + n ) O(m+n) O(m+n), 空间复杂度为 O ( 1 ) O(1) O(1)
2) 可以,将顺序表A中较小元素插入到B中即可,算法如下:

void meger2(SqList *&A, SqList *&B)
	int i=0,j=0,k;
	while(i< A->length)
		if (A->data[i] > B->data[B->length-1]) //若A->data[i]大于B中所有元素
		 
			B->data[B->length]=A->data[i];  //将A->data[i]插入到B末尾
			B->length++; i++;
		
		else if(A->data[i] < B->data[j])
			for(k=B->length-1; k>=j; k--)
				B->data[k+1] = B->data[k]; //将元素B->data[j]及之后的元素依次后移
			B->data[j]=A->data[i]; //在位置j处插入
			B->length++; //顺序表长度加1
			i++; j++;
		
		else j++;

	

本算法的时间复杂度 O ( m ∗ n ) O(m*n) O(mn), 空间复杂度为 O ( 1 ) O(1) O(1)
3) 将顺序表A的后半部分插入到前半部分中,使整个表有序。算法如下:

void merge3(SqList *&A,int m,int n)
	int i=0,j=m,k; //j扫描后半部分的有序表,并记录有序表前半部分的长度
	ElemType tmp;
	while(j< A->length && i<j)
		if(A->data[j] > A->data[j-1]) //整个表有序,退出循环
			break;
		else if (A->data[j] < A->data[i]) //将A->data[i]插入到前半部分中
		
			tmp=A->data[j];
			for(k=j-1; k>=i; k--) //将A->data[i]及之后的元素后移
				A->data[k+1] = A->data[k];
			A->data[i]=tmp;  //将A->data[j]插入到i处
			i++; j++;
		
		else i++;
	


本算法的时间复杂度为 O ( m ∗ n ) O(m*n) O(mn), 空间复杂度为 O ( 1 ) O(1) O(1)
完整代码如下:

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

#define MaxSize 50
typedef int ElemType;
typedef struct 
	ElemType data[MaxSize];
	int length;
SqList;

void DispList(SqList *L)  //输出L中所有的元素
	int i;
	if (L->length == 0) return;
	for (i = 0; i < L->length; i++)
		printf("%d ", L->data[i]);
	printf("\\n");


void meger1(SqList *&A, SqList *&B, SqList *&C) 
	int i = 0, j = 0, k = 0; //i扫描A,j扫描B
	while (i < A->length && j < B->length)
	
		if (A->data[i] < B->data[j])
		
			C->data[k] = A->data[i];
			i++; k++;
		
		else
		
			C->data[k] = B->data[j];
			j++; k++;
		
	

	while (i < A->length)  //若A未扫描完,则将A剩余的元素加到C中
		C->data[k] = A->data[i];
		i++; k++;
	

	while (j < B->length)  //若B未扫描完,则将B剩余的元素加到C中
		C->data[k] = B->data[j];
		j++; k++;
	
	C->length = k;


void meger2(SqList *&A, SqList *&B) 
	int i = 0, j = 0, k;
	while (i < A->length) 
		if (A->data[i] > B->data[B->length - 1]) //若A->data[i]大于B中所有元素
		
			B->data[B->length] = A->data[i];  //将A->data[i]插入到B末尾
			B->length++; i++;
		
		else if (A->data[i] < B->data[j]) 
			for (k = B->length - 1; k >= j; k--)
				B->data[k + 1] = B->data[k]; //将元素B->data[j]及之后的元素依次后移
			B->data[j] = A->data[i]; //在位置j处插入
			B->length++; //顺序表长度加1
			i++; j++;
		
		else j++;

	


void merge3(SqList *&A, int m, int n) 
	int i = 0, j = m, k; //j扫描后半部分的有序表,并记录有序表前半部分的长度
	ElemType tmp;
	while (j < A->length && i < j) 
		if (A->data[j] > A->data[j - 1]) //整个表有序,退出循环
			break;
		else if (A->data[j] < A->data[i]) //将A->data[i]插入到前半部分中
		
			tmp = A->data[j];
			for (k = j - 1; k >= i; k--) //将A->data[i]及之后的元素后移
				A->data[k + 1] = A->data[k];
			A->data[i] = tmp;  //将A->data[j]插入到i处
			i++; j++;
		
		else i++;
	



int main()

	SqList *A = (SqList*)malloc(sizeof(SqList));
	A->length = 0;
	A->data[0] = 3;
	A->data[1] = 7;
	A->data[2] = 15;
	A->data[3] = 18;
	A->data[4] = 26;
	A->length = 5;

	SqList *B = (SqList*)malloc(sizeof(SqList));
	B->length = 0;
	B->data[0] = 4;
	B->data[1] = 11;
	B->data[2] = 20;
	B->length = 3;

	SqList *C = (SqList*)malloc(sizeof(SqList));
	C->length = 0;

	SqList *A2 = (SqList*)malloc(sizeof(SqList));
	A2->length = 0;
	A2->data[0] = 3;
	A2->data[1] = 7;
	A2->data[2] = 11;
	A2->data[3] = 20;
	A2->data[4] = 4;
	A2->data[5] = 8;
	A2->data[6] = 16;
	A2->length = 7;

	DispList(A);
	DispList(B);

	//1)第一种方法合并
	//meger1(A,B,C);
	//DispList(C);

	//2) 第二种方法合并
	meger2(A, B);
	DispList(B);



	//3) 对A2进行排序
 	//DispList(A2);
 	//merge3(A2,4,3);
 	//DispList(A2);

	free(A);
	free(B);
	free(C);
	free(A2);

	system("pause");
	return 0;



效果如下:

图(1) 使用meger2()方法,将顺序表A、B进行合并为一个顺序表

图(2) 使用merge3()方法,对顺序表A2进行从小到大排序

以上是关于顺序表A和B的合并与排序的主要内容,如果未能解决你的问题,请参考以下文章

排序算法--归并排序

合并顺序表

[Data Structure & Algorithm] 归并排序

Javascript按字母顺序排序并将所有双精度数移动到数组的末尾

有A和B两个顺序表,数据都为从小到大排列,如何把它们合并从一个顺序表C

排序---选择排序