数据结构-顺序表

本文详细介绍了如何使用数组实现线性表数据结构,包括初始化、获取长度、元素获取、定位、插入、删除等操作,同时展示了C++中引用与指针的区别及应用,以及数组在特定场景下的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

    使用数组存储,空间大小有限制,内存地址连续,可随机访问,一般不进行插入和删除操作,适合数据量确定和较小的情况。

代码

/*
**	sqlist create by yubo.wang 2018.9.12
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 128
typedef char ElemType;

typedef struct
{
	ElemType data[MAXSIZE];
	int length;
}SqList;

void jose(int n, int m);

void InitList(SqList &L)
{
	memset(L.data, 0, sizeof(L.data));
	L.length = 0;
}

int GetLength(SqList L)
{
	return L.length;
}

/*get data by index i,and save in e,return 0 if i invalid else 1*/
int GetElem(SqList L,int i,ElemType &e)
{
	if(i<1 || i>L.length)
		return 0;
	else
	{
		e = L.data[i-1];
		return 1;
	}
}

/*find x and return index*/
int Locate(SqList L,ElemType x)
{
	int i = 0;
	while(L.data[i] != x)
		i++;
	if(i>L.length)
		return 0;
	else
		return(i+1);
}

int InsElem(SqList &L,ElemType x,int i)
{
	int j;
	if(i<1 || i>L.length+1)
		return 0;
	for(j=L.length; j>i; j--)
		L.data[j] = L.data[j-1];
	L.data[i-1] = x;
	L.length++;
	return 1;
}

int DelElem(SqList &L, int i)
{
	int j;
	if(i<1 || i>L.length)
		return 0;
	for(j=i; j<L.length; j++)
		L.data[j-1] = L.data[j];
	L.length--;
	return 1;	
}

void DispList(SqList L)
{
	int i = 0;
	for(i=0; i<L.length; i++)
		printf("%c ", L.data[i]);
	printf("\n");
}

/*
C++ 函数传参:
(1) 将变量名作为实参和形参。这时传给形参的是变量的值,传递是单向的。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同一个存储单元。// 同 c
(2) 传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种通过形参指针可以改变实参的值。// 同 c
(3) C++提供了 传递变量的引用。形参是引用变量,和实参是一个变量,调用函数时,形参(引用变量)指向实参变量单元。这种通过形参引用可以改变实参的值。
*/
void swap(int& x, int& y)
{
	int temp;
	temp = x; /* 保存地址 x 的值 */
	x = y;    /* 把 y 赋值给 x */
	y = temp; /* 把 x 赋值给 y  */
	return;
}

int vals[] = {10, 20, 30, 40, 50};
/*
(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。
*/
int& setValues( int i )
{
	return vals[i];   // 返回第 i 个元素的引用
}

/*	C++ 引用 vs 指针
不存在空引用。引用必须连接到一块合法的内存。
一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
引用必须在创建时被初始化。指针可以在任何时间被初始化。
*/
void fun_quote()
{
	int i;
	int& r = i;
	i=1;
	printf("%d,%d->", i,r);
	r=2;
	printf("%d,%d->", i,r);
	int y=3;
	r=y;//一旦引用被初始化为一个对象,就不能被指向到另一个对象,这里是指向其他对象了吗?
	printf("%d,%d\n", i,r);

	//C++ 把引用作为参数
	int a = 100;
	int b = 200;
	printf("%d,%d->", a,b);
	swap(a, b);
	printf("%d,%d\n", a,b);

	//C++ 把引用作为返回值
	printf("%d,%d->", vals[1],vals[3]);	
	setValues(1) = 60; // 改变第 2 个元素
	setValues(3) = 70; // 改变第 4 个元素
	printf("%d,%d\n", vals[1],vals[3]);	
}

int main()
{
	int i;
	ElemType e;
	SqList L;

	InitList(L);
	InsElem(L,'a',1);
	InsElem(L,'b',2);
	InsElem(L,'c',3);
	InsElem(L,'d',4);
	InsElem(L,'e',5);
	InsElem(L,'f',6);
	printf("SqList: ");
	DispList(L);
	printf("length:%d\n", GetLength(L));

	i=3;
	GetElem(L,i,e);
	printf("index %d data is:%c\n", i,e);

	e='e';
	printf("data %c index is:%d\n", e,Locate(L,e));

	i=4;
	printf("delete index %d data %c\n", i, L.data[i-1]);
	DelElem(L,i);

	i=2;
	e='w';
	printf("insert index %d data %c\n", i, e);
	InsElem(L,e,2);

	printf("SqList: ");
	DispList(L);

	jose(20, 5);

	fun_quote();
	return 0;
}

/*
**	求两个集合A和B的公共元素放在C中(单个集合中没有重复的元素)
*/
void common(SqList A,SqList B,SqList &C)
{
	int i,j;
	C.length = 0;
	for(i=0; i<A.length; i++)
	{
		j=0;
		while(j<B.length && B.data[j] != A.data[i])
			j++;
		if(j<B.length)
		{
			C.data[C.length++] = A.data[i];
		}
	}
}

/*
**	将两个有序递增A和B归并放在C中,时间复杂度O(A.length+B.length)
*/
void merge(SqList A,SqList B,SqList &C)
{
	int i=0,j=0,k=0;
	while(i<A.length && j<B.length)
	{
		if(A.data[i] < B.data[j])
		{
			C.data[k++] = A.data[i++];
		}
		else if(A.data[i] > B.data[j])
		{
			C.data[k++] = B.data[j++];
		}
		else
		{
			C.data[k++] = A.data[i++];
			C.data[k++] = B.data[j++];
		}
	}
	/*剩余的直接拷贝*/
	while(i<A.length)
	{
		C.data[k++] = A.data[i++];
	}
	while(j<B.length)
	{
		C.data[k++] = B.data[j++];
	}
	C.length = k;
}

/*
**	n只猴子选大王,所以猴子按1,2,...n编号坐一圈,从1号猴子开始按1,2...m报数,凡报到m号的退出圈外,如此循环直到最后一只就是大王
*/
void jose(int n, int m)
{
	int mon[MAXSIZE];
	int i,d,count;
	/*给n只猴子编号*/
	for(i=0; i<n; i++)
		mon[i] = i+1;

	/*打印初始值*/
	printf("in:");
	for(i=0; i<n; i++)
		printf("%d ", mon[i]);
	printf("\n");

	/*打印出圈编号顺序*/
	printf("out:");
	count = 0;
	i = -1;
	while(count < n)//count出圈的个数->n
	{
		d=0;
		while(d<m)//每一轮报数从d=0遍历到m
		{
			i=(i+1)%n;//i是保证从0->n->0的无线循环
			if(mon[i] != 0)//遇已经出圈编号跳过遍历
				d++;
		}
		printf("%d ", mon[i]);//打印出圈的编号
		mon[i] = 0;//出圈编号值0标志
		count++;//出圈的个数加1
	}
	printf("\n");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值