顺序表的基本操作实现与顺序表的合并、归并的实现(C语言版)

    这是我通过我所学的及参考了一些伪代码后写出的具体实现代码,分享给大家一起互相借鉴,如有写的不好的,多多指教一下,哈哈。大笑大笑

        主要实现的有顺序表的构造、初始化、创建、插入、删除、查找和遍历(使用了动态分配的一维数组实现和使用了静态分配的数组实现,具体请看代码)以及顺序表的合并和归并的实现。

代码如下编写软件为vs2017):


头文件"CAF.h"代码:

#pragma once

/*
 * 名称:《CAF.h》 —— Constants And Functions(常量和函数)
 * 作用:用来定义顺序表的各种常量和函数
**/

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

/* 函数结果状态代码 */
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE -1
#define OVERFLOW -2

#define MAXSIZE 1000		//初始分配量
#define LISTINCREMENT 10	//线性表存储空间的分配增量

typedef int Status;		//函数名,返回值为函数结果状态代码
typedef int ElemType;		//数据类型

/* 构造顺序表-1 */
typedef struct Sqlist_1
{
	ElemType data[MAXSIZE];
	int length;
}Sqlist_1;

/* 构造顺序表-2 */
typedef struct Sqlist_2
{
	ElemType *elem;		//存储空间基址
	int length;			//当前长度
	int listsize;		//当前分配的存储容量
}Sqlist_2;

/* 菜单 */
void Menu();

/* 顺序表的初始化-1 */
Status InitList_Sq1(Sqlist_1 **L1);

/* 顺序表的初始化-2 */
Status InitList_Sq2(Sqlist_2 **L2);

/* 顺序表的创建-1 */
Status CreateList_Sq1(Sqlist_1 **L1, int len);

/* 顺序表的创建-2 */
Status CreateList_Sq2(Sqlist_2 **L2, int len);

/* 顺序表的遍历-1 */
void Plist1(Sqlist_1 *L1);

/* 顺序表的遍历-2 */
void Plist2(Sqlist_2 *L2);

/* 顺序表查找-1 */
Status GetElem1(Sqlist_1 *L1, int i, ElemType *e);

/* 顺序表查找-2 */
Status GetElem2(Sqlist_2 *L2, int i, ElemType *e);

/* 顺序表插入-1 */
Status ListInsert1(Sqlist_1 **L1, int i, ElemType e);

/* 顺序表插入-2 */
Status ListInsert2(Sqlist_2 **L2, int i, ElemType e);

/* 顺序表删除-1 */
Status ListDelete1(Sqlist_1 **L1, int i, ElemType *e);

/* 顺序表删除-2 */
Status ListDelete2(Sqlist_2 **L2, int i, ElemType *e);

/* 合并顺序表 */
void Union(Sqlist_1 **L1, Sqlist_2 *L2);

/* 按元素值查找 */
int LocateElem(Sqlist_1 *L1, ElemType e);

/* 归并顺序表-1 */
void MergeList(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_1 **L3);

/* 冒泡排序表1和表2 */
void Show(Sqlist_1 **L1, Sqlist_2 **L2);

/* 归并顺序表-2 */
void MergeList_sq(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_2 **L3);


实现函数的文件"CAF.c"代码:

/*
 * 名称:《CAF.c》
 * 作用:实现《CAF.h》中定义的函数
**/

#include "CAF.h"

/* 菜单 */
void Menu()
{
	printf("************************* 菜单 *************************\n\n");
	printf("1、初始化顺序表\n\n2、创建顺序表\n\n3、遍历顺序表\n\n4、顺序表插入\n\n5、顺序表删除\n\n6、顺序表查找\n\n");
	printf("7、合并顺序表\n\n8、归并顺序表\n");
	printf("\n********************************************************\n");
}

/* 顺序表的初始化-1 */
Status InitList_Sq1(Sqlist_1 **L1)
{
	*L1 = (Sqlist_1 *)malloc(sizeof(Sqlist_1));
	
	if ((*L1) == NULL)
		exit(OVERFLOW);
	
	(*L1)->length = 0;	//线性表长度赋为0,空表

	return OK;
}

/* 顺序表的初始化-2 */
Status InitList_Sq2(Sqlist_2 **L2)
{
	*L2 = (Sqlist_2 *)malloc(sizeof(Sqlist_2));
	(*L2)->elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
	
	if ((*L2) == NULL)
		exit(OVERFLOW);
	if ((*L2)->elem == NULL)
		exit(OVERFLOW);
	
	(*L2)->length = 0;			//当前为空表,长度为0
	(*L2)->listsize = MAXSIZE;	//初始分配存储容量

	return OK;
}

/* 顺序表的创建-1 */
Status CreateList_Sq1(Sqlist_1 **L1, int len)
{
	int i;
	(*L1)->length = len;

	printf("**--** 请输入数据创建顺序表1 **--** :  ");
	for (i = 0; i < (*L1)->length; i++)
	{
		scanf("%d", &(*L1)->data[i]);
	}
	
	return OK;
}

/* 顺序表的创建-2 */
Status CreateList_Sq2(Sqlist_2 **L2, int len)
{
	int i;
	(*L2)->length = len;

	printf("**--** 请输入数据创建顺序表2 **--** :  ");
	for (i = 0; i < (*L2)->length; i++)
	{
		scanf("%d", &(*L2)->elem[i]);
	}

	return OK;
}

/* 顺序表的遍历-1 */
void Plist1(Sqlist_1 *L1)
{
	int i;
	printf("\n************************** 表中数据 **************************\n\n");
	for (i = 0; i < L1->length; i++)
	{
		printf("%d  ", L1->data[i]);
	}
	printf("\n\n***************************************************************\n");
}

/* 顺序表的遍历-2 */
void Plist2(Sqlist_2 *L2)
{
	int i;
	printf("\n************************** 表中数据 **************************\n\n");
	for (i = 0; i < L2->length; i++)
	{
		printf("%d  ", L2->elem[i]);
	}
	printf("\n\n***************************************************************\n");
}

/* 顺序表查找-1 */
Status GetElem1(Sqlist_1 *L1, int i, ElemType *e)
{
	if (L1->length == 0 || i < 1 || i > L1->length)
	{
		return ERROR;
	}

	*e = L1->data[i - 1];

	return OK;
}

/* 顺序表查找-2 */
Status GetElem2(Sqlist_2 *L2, int i, ElemType *e)
{
	if (L2->length == 0 || i < 1 || i > L2->length)
	{
		return ERROR;
	}

	*e = L2->elem[i - 1];

	return OK;
}

/* 顺序表插入-1 */
Status ListInsert1(Sqlist_1 **L1, int i, ElemType e)
{
	int k;
	if ((*L1)->length == MAXSIZE)	//表满
	{
		return ERROR;
	}
	if (i < 1 || i >(*L1)->length + 1)	//i不在范围
	{
		return ERROR;
	}

	if (i <= (*L1)->length)		//插入位置不在表尾
	{
		//插入位置后所有元素后移一位
		for (k = (*L1)->length - 1; k >= i - 1; k--)
		{
			(*L1)->data[k + 1] = (*L1)->data[k];
		}
	}

	(*L1)->data[i - 1] = e;		//插入新元素
	(*L1)->length++;				//表长+1

	return OK;
}

/* 顺序表插入-2 */
Status ListInsert2(Sqlist_2 **L2, int i, ElemType e)
{
	ElemType *q;		//q为插入位置
	ElemType *p;

	if (i < 1 || i >(*L2)->length + 1)	//i不合法
		return ERROR;
	
	if ((*L2)->length >= (*L2)->listsize)	//空间已满,增加分配
	{
		ElemType *newbase;
		newbase = (ElemType *)realloc((*L2)->elem, ((*L2)->listsize + LISTINCREMENT) * sizeof(ElemType));
		if (newbase == NULL)
			exit(OVERFLOW);				//分配失败
		(*L2)->elem = newbase;			//新基址
		(*L2)->listsize += LISTINCREMENT;	//增加存储容量
	}

	q = &(*L2)->elem[i - 1];
	for (p = &(*L2)->elem[(*L2)->length - 1]; p >= q; p--)	//插入位置及之后的元素右移
		*(p + 1) = *p;
	*q = e;				//插入e
	(*L2)->length++;		//表长+1

	return OK;
}

/* 顺序表删除-1 */
Status ListDelete1(Sqlist_1 **L1, int i, ElemType *e)
{
	int k;

	if ((*L1)->length == 0)
		return ERROR;
	if (i < 1 || i > (*L1)->length)
		return ERROR;
	
	*e = (*L1)->data[i - 1];

	if (i < (*L1)->length)
	{
		for (k = i; k < (*L1)->length; k++)
		{
			(*L1)->data[k - 1] = (*L1)->data[k];
		}

	}

	(*L1)->length--;

	return OK;
}

/* 顺序表删除-2 */
Status ListDelete2(Sqlist_2 **L2, int i, ElemType *e)
{
	ElemType *p;
	ElemType *q;

	if (i < 1 || i >(*L2)->length)
		return ERROR;

	p = &(*L2)->elem[i - 1];				//被删除元素的位置
	*e = *p;								//被删除元素赋给e
	q = (*L2)->elem + (*L2)->length - 1;	//表尾元素的位置

	for (++p; p <= q; p++)
	{
		*(p - 1) = *p;
	}

	(*L2)->length--;

	return OK;
}

/* 合并顺序表 */
void Union(Sqlist_1 **L1, Sqlist_2 *L2)
{
	//将所有在表2中但不在表1中的数据元素插入到表1中
	
	ElemType e2;
	int i;
	int L1_len, L2_len;
	//求顺序表长度
	L1_len = (*L1)->length;
	L2_len = L2->length;
	for (i = 1; i <= L2_len; i++)
	{
		GetElem2(L2, i, &e2);		//取表2中第i个元素赋给e2
		if (!LocateElem(*L1, e2))	//如果表达式为真,则L1中不存在和e相同的元素,则插入其中
		{
			ListInsert1(L1, ++L1_len, e2);
		}

	}
}

/* 按元素值查找 */
int LocateElem(Sqlist_1 *L1, ElemType e)
{
	int i = 0;
	while (i < L1->length && L1->data[i] != e)
	{
		i++;
	}
	if (i >= L1->length)
		return 0;		//没找到相同的,返回假
	else
		return i + 1;	//找到相同的,返回真
}

/* 归并顺序表 */
void MergeList(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_1 **L3)
{
	//已知顺序表L1和L2中的数据元素按值非递减排列
	//归并L1和L2得到新的顺序表L3,L3的数据元素也按值非递减排列

	ElemType ai, bj;
	//InitList_Sq1(L3);		//初始化L3
	int i = 1, j = 1, k = 0;
	int L1_len, L2_len;
	L1_len = L1->length;
	L2_len = L2->length;
	while ((i <= L1_len) && (j <= L2_len))		//L1和L2均非空
	{
		GetElem1(L1, i, &ai);
		GetElem2(L2, j, &bj);
		if (ai <= bj)
		{
			ListInsert1(L3, ++k, ai);
			++i;
		}
		else
		{
			ListInsert1(L3, ++k, bj);
			++j;
		}
	}
	//插入剩余元素
	while (i <= L1_len)
	{
		GetElem1(L1, i++, &ai);
		ListInsert1(L3, ++k, ai);
	}
	while (j <= L2_len)
	{
		GetElem2(L2, j++, &bj);
		ListInsert1(L3, ++k, bj);
	}
}

/* 冒泡排序表1和表2 */
void Show(Sqlist_1 **L1, Sqlist_2 **L2)
{
	int i1, j1, i2, j2;
	int N1, N2;
	ElemType temp1, temp2;
	N1 = (*L1)->length;
	N2 = (*L2)->length;
	for (i1 = 0; i1 < N1 - 1; i1++)
	{
		for (j1 = 0; j1 < N1 - i1 - 1; j1++)
		{
			if ((*L1)->data[j1] > (*L1)->data[j1 + 1])
			{
				temp1 = (*L1)->data[j1];
				(*L1)->data[j1] = (*L1)->data[j1 + 1];
				(*L1)->data[j1 + 1] = temp1;
			}
		}
	}
	printf("表1排序后:");
	Plist1(*L1);
	printf("\n-------------------------------------------------------\n\n");
	for (i2 = 0; i2 < N2 - 1; i2++)
	{
		for (j2 = 0; j2 < N2 - i2 - 1; j2++)
		{
			if ((*L2)->elem[j2] >(*L2)->elem[j2 + 1])
			{
				temp2 = (*L2)->elem[j2];
				(*L2)->elem[j2] = (*L2)->elem[j2 + 1];
				(*L2)->elem[j2 + 1] = temp2;
			}
		}
	}
	printf("表2排序后:");
	Plist2(*L2);
	printf("\n-------------------------------------------------------\n\n\n");
}

/* 归并顺序表-2 */
void MergeList_sq(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_2 **L3)
{
	//已知顺序表L1和L2中的数据元素按值非递减排列
	//归并L1和L2得到新的顺序表L3,L3的数据元素也按值非递减排列
	ElemType *pa, *pb, *pc;
	ElemType *pa_last, *pb_last;
	pa = L1->data;				//表一元素的首地址
	pb = L2->elem;				//表二元素的首地址
	(*L3)->listsize = (*L3)->length = L1->length + L2->length;		//新表初始分配长度
	pc = (*L3)->elem = (ElemType *)malloc((*L3)->listsize * sizeof(ElemType));	//分配空间
	if (!((*L3)->elem))
		exit(OVERFLOW);		//存储分配失败
	pa_last = L1->data + L1->length - 1;		//表一最后一个元素的地址
	pb_last = L2->elem + L2->length - 1;		//表二最后一个元素的地址
	while (pa <= pa_last && pb <= pb_last)		//归并
	{
		if (*pa <= *pb)
			*pc++ = *pa++;
		else
			*pc++ = *pb++;
	}
	while (pa <= pa_last)		//插入表1的剩余元素
	{
		*pc++ = *pa++;
	}
	while (pb <= pb_last)		//插入表2的剩余元素
	{
		*pc++ = *pb++;
	}
}


主函数代码:

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

/*
 *
 * 项目名称:【 顺序表的基本操作实现及其使用 】
 * 【说明】:
 * < 1.实现顺序表的构造、初始化、创建、插入、删除、查找、遍历这几项基本操作 >
 * < 2.实现了顺序表的合并和顺序表的归并 >
 * 作者:踏歌行彡轻盈
 * 日期:2018-4-23
 *
**/

int main()
{
	Sqlist_1 *L1;
	Sqlist_2 *L2;
	Sqlist_1 *L3;
	Sqlist_2 *L4;
	int len1, len2;			//要创建的顺序表的长度1和长度2
	int choice;				//菜单选择
	int e, i;
	int	e1, i1;

	Menu();		//菜单

	while (1)
	{
		printf("\n\n*-** 请选择(按数字0退出) **-*  ");
		fflush(stdin);
		scanf("%d", &choice);
		fflush(stdin);
		printf("\n");
		switch (choice)
		{
		case 1:
			/* 使用两种方式初始化顺序表 */
			InitList_Sq1(&L1);
			InitList_Sq2(&L2);
			InitList_Sq1(&L3);
			InitList_Sq2(&L4);
			break;
		case 2:
			/* 使用两种方式创建顺序表 */
			printf("请输入要创建的顺序表的长度1和长度2: ");
			fflush(stdin);
			scanf("%d%d", &len1, &len2);
			fflush(stdin);
			CreateList_Sq1(&L1, len1);
			CreateList_Sq2(&L2, len2);
			break;
		case 3:
			/* 遍历顺序表 */
			printf("|** --------------------------------------------------------------------- **|\n");

			printf("\n|*|- *************************** 遍历顺序表 *************************** -|*|\n\n");
			
			Plist1(L1);

			printf("\n|** --------------------------------------------------------------------- **|\n");
			
			Plist2(L2);

			if (L3->length != 0)
			{
				printf("\n|** --------------------------------------------------------------------- **|\n");

				Plist1(L3);
			}

			if (L4->length != 0)
			{
				printf("\n|** --------------------------------------------------------------------- **|\n");

				Plist2(L4);
			}

			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			break;
		case 4:
			printf("|** --------------------------------------------------------------------- **|\n\n");

			printf("\n--**-- 请输入表1要插入的元素和要插入的位置 --**-- : ");
			fflush(stdin);
			scanf("%d%d", &e, &i);
			fflush(stdin);
			ListInsert1(&L1, i, e);
			Plist1(L1);
			printf("\n\n|**| -------------------------------------------------------------- |**|\n\n");
			printf("\n--**-- 请输入表2要插入的元素和要插入的位置 --**-- : ");
			fflush(stdin);
			scanf("%d%d", &e, &i);
			fflush(stdin);
			ListInsert2(&L2, i, e);
			Plist2(L2);

			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			break;
		case 5:
			printf("|** --------------------------------------------------------------------- **|\n\n");

			printf("\n--**-- 请输入表一中要删除的元素位置:");
			fflush(stdin);
			scanf("%d", &i);
			fflush(stdin);
			ListDelete1(&L1, i, &e1);
			printf("|-**-| 被删除的元素为:%d |-**-|\n\n", e1);
			printf("|*-*------------------------ 删除后 ------------------------*-*|\n\n");
			Plist1(L1);

			printf("\n\n|**| -------------------------------------------------------------- |**|\n\n");

			printf("\n--**-- 请输入表二中要删除的元素位置:");
			fflush(stdin);
			scanf("%d", &i);
			fflush(stdin);
			ListDelete2(&L2, i, &e1);
			printf("|-**-| 被删除的元素为:%d |-**-|\n\n", e1);
			printf("|*-*------------------------ 删除后 ------------------------*-*|\n\n");
			Plist2(L2);

			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			break;
		case 6:
			printf("|** --------------------------------------------------------------------- **|\n\n");

			printf("\n请输入在表一中要查找的元素的位置:");
			fflush(stdin);
			scanf("%d", &i1);
			fflush(stdin);
			GetElem1(L1, i1, &e1);
			printf("该位置的元素为:%d\n", e1);

			printf("\n\n|**| -------------------------------------------------------------- |**|\n\n");

			printf("\n请输入在表二中要查找的元素的位置:");
			fflush(stdin);
			scanf("%d", &i1);
			fflush(stdin);
			GetElem2(L2, i1, &e1);
			printf("该位置的元素为:%d\n", e1);

			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			break;
		case 7:
			printf("|** --------------------------------------------------------------------- **|\n\n");

			printf("\n|**|-*-*-*-*-*-*-*-*-*-*- 将表2合并到表1前 -*-*-*-*-*-*-*-*-*-*-|**|\n\n");
			Plist1(L1);
			printf("\n|** --------------------------------------------------------------------- **|\n");
			Plist2(L2);
			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			printf("\n\n|**|-*-*-*-*-*-*-*-*-*-*- 将表2合并到表1后 -*-*-*-*-*-*-*-*-*-*-|**|\n\n");
			Union(&L1, L2);
			Plist1(L1);

			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			break;
		case 8:
			printf("|** --------------------------------------------------------------------- **|\n\n\n");

			Show(&L1, &L2);
			printf("|*-*|-*-*-*-*-*-*-*-*-*-*-*-*- 归并方法一 - 将表1和表2归并到表3后 -*-*-*-*-*-*-*-*-*-*-*-*-|*-*|\n\n");
			MergeList(L1, L2, &L3);
			Plist1(L3);

			printf("\n|** --------------------------------------------------------------------- **|\n");

			printf("|*-*|-*-*-*-*-*-*-*-*-*-*-*-*- 归并方法二 - 将表1和表2归并到表4后 -*-*-*-*-*-*-*-*-*-*-*-*-|*-*|\n\n");
			MergeList_sq(L1, L2, &L4);
			Plist2(L4);
			printf("\n\n|** --------------------------------------------------------------------- **|\n");
			break;
		case 0:
			return 0;
			break;
		}
	}
	
	return 0;
}


程序运行效果截图:














猜你喜欢

转载自blog.csdn.net/qq_41221623/article/details/80053710