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

52 篇文章 2 订阅

用顺序表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进行从小到大排序
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanqima

一键三连,多多益善

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值