数据结构 顺序表的相关算法操作

例题一:比较两个顺序表的大小

比较是通过由两个表的首数据一次向后遍历,逐个比较。如遇到A.elem[i] > B.elem[i],则A>B.如遇到A.elem[i] < B.elem[i]则B<A,若A.elem[i] = B.elem[i]则下一个数据继续比较。

#include<stdio.h>
#include<string.h>
const int LIST_INIT_SIZE = 100;
const int LISTINCREMENT = 10;
typedef struct {
	char *elem;
	int length;
	int listsize;
	int listincrementsize;
}SqList;

void InitList(SqList &L, int maxsize = LIST_INIT_SIZE, int incresize = LISTINCREMENT)
{
	L.elem = new char[maxsize];
	L.length = 0;
	L.listsize = maxsize;
	L.listincrementsize = incresize;
}

int compare(SqList A, SqList B)
{
	int j = 0;
	while (j < A.length&&j < B.length)
	{
		if (A.elem[j] < B.elem[j])
			return (-1);
		else if (A.elem[j] > B.elem[j])
			return (1);
		else j++;
	}
	if (A.length = B.length)
		return(0);
	else if (A.length < B.length)
		return (-1);
	else
		return (1);
}

void main()
{
	int i;
	SqList A,B;
	InitList(A);
	InitList(B);
	strcpy(A.elem, "abcdefegsgfd");    //对顺序表A进行赋值
	A.length = 12;
	strcpy(B.elem, "abcdfksdflpsf");   //对顺序表B进行赋值
	B.length = 13;
	i = compare(A, B);
	if (i == 0)
		printf("A和B相等。\n");
	else if (i < 0)
		printf("A小于B。\n");
	else
		printf("A大于B。\n");
}

定义两个顺序表,先定义顺序表数据结构,再定义顺序表变量,然后为其赋值时,可以循环赋值也可以用 strcpy() 函数直接赋值。对两个表进行比较时首先定义一个变量 j , 当 j 小于两个表的长度时循环,比较各个数据,若不同则返回相应的值,若相同则比较下一个数据。当跳出循环时,继续执行后续程序时,说明两表前面这部分数据相同,然后比较其表长。

总的来说就两步:一是 j 小于两表长度时比较单个数据大小,二是 j 超过某一个表长度时比较表长。

---------------------------------------------------------------------------------------------------------------------------------

例题二:利用尽量少的辅助空间,将顺序表前m个数据和后n个数据整体互换位置

算法一:利用辅助空间c,先将后n个数的第一个数提出放在c上,然后将前个数进行右移,再将c提前。首先定义两个循环变量i,j,然后大循环就是对于后m个数,for(j=0;j<m;j++); 先将A.elem[m+j]赋值给c,然后进入小循环,for(i=m+j ; i>j ; i--); 此处括号里的 i=m+j ;是因为最初 i 指向 c,但是由于后面的右移操作导致前m个数的下标会加一,所以要加上 j . 范围 i>j 的判断是因为小循环要执行m次,所以直接m+j-m得到 i>j. 最后一步是将c赋给前面的数,最初时A.elem[0],后面要加一所以是A.elem[j]; 代码如下:

#include<stdio.h>
#include<string.h>
const int LIST_INIT_SIZE = 100;
const int LISTINCREMENT = 10;
typedef struct {
	char *elem;
	int length;
	int listsize;
	int listincrementsize;
}SqList;

void InitList_Sq(SqList &L, int maxsize = LIST_INIT_SIZE, int incresize = LISTINCREMENT)
{
	L.elem = new char[maxsize];
	L.length = 0;
	L.listsize = maxsize;
	L.listincrementsize = incresize;
}

void exchange1(SqList &A, int m, int n)
{
	int i, j;   //定义i,j 用于循环分别表示前m个数据和后n个数据
	char c;       //辅助空间
	for (j = 0; j < n; j++)  //对后n个数据循环
	{
		c = A.elem[m + j];     //将后n个数据的第一个数据拿出来 即A.elem[m+j];
		for (i = m + j; i > j; i--)   //对前m个数据进行循环右移
			A.elem[i] = A.elem[i - 1];  
		A.elem[j] = c;    //再将之前提出的数放在前面的位置
	}
}

void main()
{
	int i;
	SqList A;
	InitList_Sq(A);
	strcpy(A.elem, "abcdefghijklmn");
	A.length = 14;
	exchange1(A, 7, 7);
	for (i = 0; i < 14; i++)
		printf("%c ", A.elem[i]);
}

算法二:构造辅助函数void invert(char R[], int s, int t),功能是实现数组R[s]到R[t]之间数据的逆置。则调用该函数三次,先整体逆置,再将前n个逆置,最后将后m个逆置即可。对于逆置函数,定义辅助空间和循环变量,然后循环,for (i = s; i <= (s + t) / 2; i++) 其中 i 初始值指向R[s], 由于共有s+t个数 所以循环 i<=(s+t)/2 次,互换时 R[t + s - i],是因为此处原本是R[t],但是由于后面循环要减一,所以要减去i,为保证下标不变所以加上s。代码如下:

#include<stdio.h>
#include<string.h>
const int LIST_INIT_SIZE = 100;
const int LISTINCREMENT = 10;
typedef struct {
	char *elem;
	int length;
	int listsize;
	int listincrementsize;
}SqList;

void InitList_Sq(SqList &L, int maxsize = LIST_INIT_SIZE, int incresize = LISTINCREMENT)
{
	L.elem = new char[maxsize];
	L.length = 0;
	L.listsize = maxsize;
	L.listincrementsize = incresize;
}

void invert(char R[], int s, int t)
{
	char c;
	int i;
	for (i = s; i <= (s + t) / 2; i++)
	{
		c = R[i];
		R[i] = R[t + s - i];  //此处原本是R[t],但是由于后面循环要减一,所以要减去i,为保证下标不变所以加上s
		R[t + s - i] = c;
	}
}
void exchange2(SqList A, int m, int n)
{
	invert(A.elem, 0, m + n - 1);
	invert(A.elem, 0, n - 1);
	invert(A.elem, n, m + n - 1);
}

void main()
{
	int i;
	SqList A;
	InitList_Sq(A);
	strcpy(A.elem, "abcdefghijklmn");
	A.length = 14;
	exchange2(A, 7, 7);
	for (i = 0; i < 14; i++)
		printf("%c ", A.elem[i]);
}

-------------------------------------------------------------------------------------------------------------------

例题三:含有相同元素的表B,构造表A,使其只有B中不相同的元素

本题建立一条空的A表用于存储B表中的数据,在函数体中,首先定义两个循环变量 i, j,分别对应表B和表A,再定义辅助空间e存放数据。先将B表中首数据赋值给A.elem[0],然后进入大循环,for (i = 1; i < B.length; i++)在B表中从第二个元素开始进行遍历,将B表中的数据放在e中,然后对 j 清零,进入小循环while (j < A.length&&A.elem[j] != e)开始对A表进行遍历 j++.当跳出循环时判断是 j=A.length还是A.elem[j]==e.然后选择是将e插入到A表的末尾还是直接进入下一次大循环。

#include<stdio.h>
#include<string.h>
const int LIST_INIT_SIZE = 100;
const int LISTINCREMENT = 10;
typedef struct {
	char *elem;
	int length;
	int listsize;
	int listincrementsize;
}SqList;

void InitList_Sq(SqList &L, int maxsize = LIST_INIT_SIZE, int incresize = LISTINCREMENT)
{
	L.elem = new char[maxsize];
	L.length = 0;
	L.listsize = maxsize;
	L.listincrementsize = incresize;
}

void purge_Sq(SqList &A, SqList &B)
{
	int i, j;  //i,j 分别对应检索表B和表A
	char e;
	A.elem[0] = B.elem[0];
	A.length = 1;
	for (i = 1; i < B.length; i++)
	{
		e = B.elem[i];
		j = 0;   //对A表检索时先将J清零
		while (j < A.length&&A.elem[j] != e)
			j++;
		if (j == A.length)
		{
			A.elem[A.length] = e;
			A.length++;
		}
	}
	delete[] B.elem;
	B.listsize = 0;
}

void main()
{
	int i;
	SqList A;
	SqList B;
	InitList_Sq(B);
	InitList_Sq(A);
	strcpy(B.elem, "abbbcdeeefggghijjjklmn");
	B.length = 22;
	printf("处理前B表的数据为:");
	for (i = 0; i < B.length; i++)
		printf("%c ", B.elem[i]);
	printf("\n");
	purge_Sq(A, B);
	printf("处理后把B表的数据赋给A表,为:");
	for (i = 0; i < A.length; i++)
		printf("%c ", A.elem[i]);
}

本笔记所依据的教材为严薇敏版的《数据结构及应用算法教程》

所有代码在Visual Studio 2017上均可正常运行

如有错误欢迎指出

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值