【数据结构】第二章线性结构顺序表算法思想总结

线性表由存储结构的不同可以分为顺序表链表

  1. 顺序表
    对于顺序表,首先就是熟悉类型定义,一定要熟悉增删改查的基本操作。
    类型定义
#define LIST_INIT_SIZE 100
#define LISTINCREMENT_SIZE 10
typedef struct{
ElemType*data;
int length;//当前长度
int maxsize;//当前分配的存储容量
}Sqlist;

动态分配语句为

L.elem=(ElemType*)malloc(sizeof(Elemtype)*LISTINCREMENT);
  1. 增加操作
    增加操作在各大考研习题中考察不多,代码也不难,出题方向主要是在代码细节,但代码中的基本原理需要掌握。
bool SqListInsert(SqList &L,int i,ElemType e)//在顺序表中第i个位置插入新元素e
{
	if(i<1||i>L.length+1return false;
	if(L.length>=MaxSize)
	return false;
	forint j=L.length-1;j>=i-1;j--//将第i个元素后的元素推后一位
	L.data[j+1]=L.data[j];
    L.data[i]=e;//插入元素e
    L.length++;//更新length值
    return ture;
}

注意细节:位序和数组下标的区别
时间复杂度分析:
最好情况,后移语句不执行,直接在表尾插入,元素后移;O(1)
最坏情况,后移语句执行了n次,O(n)
平均情况,Pi=1/(n+1), 1/(n+1)*(0+1+2+3+4+…+n)=n/2, O(n)

3.删除操作
删除操作在考察过程中通常不会给定位置要求删除,所以我们需要利用查找算法找到要求被删除的元素的位置,然后进行删除操作,查找常常与高效的二分查找算法相结合,删除为固定代码。

bool SqListDelete(SqList &L, int i, ElemType x)//删除顺序表L中第i个位置的元素,若成功则返回true,并将被删除的元素用引用元素e返回,否则返回false。
{
if(i<1||i>length)
return false;
e=L.Data[i-1];//注意数组下标
forint j=i;j<=length-1;j++)
L.Data[i-1]=L.Data[i];
L.length--;
return true;
}
//在一个顺序表中删除为x的元素,需要注意移动后续元素
void delete(SqList &L.ElemType x)
{
	int k=0//记录不为x的元素下标7
	for(int i=0;i<L.length;i++)
	{
		if(L[i]!=x)
		{
			L[k++]=L[i]
		}
	}
}
//删除重复的,我们运用一个工作指针
void delete_same(SqList &L)
{
	int i=0,j=1;
	for(i,j;i<L.length;j++)
	{
		if(L[i]!=L[j])
		L[++i]=L[j];
	}
	L.length=i+1;
	return true;
}

标志性语句:有序顺序表,最少时间查找。
思想:经典二分查找算法

bool binarysearch(SqList&L,ElemType x)//有序顺序表,最少时间查找,查到与后继交换,查不到则插入
{
	int l=0,r=L.length-1while(l<=r)
	{
		mid=(l+r)/2;
		if(L.data[mid]==x)
		ElemType temp=L.data[mid];
		L.data[mid]=L.data[mid+1];
		L.data[mid+1]=ElemType temp;//c语言中的逆置算法,需掌握
		return true.
		else if(L.data[mid]<x)
		l=mid+1;
		else r=mid-1;
	}
	for(int j=L.length-1;j>=l;j--)
	L.data[j+1]=L.data[j];
	L.data[r]=x;//此处在何处插入x需要对于二分查找原理有了解
	return true;
}

标志性语句:逆置算法,互换,左移
思想:明白逆置算法的原理,再对于基本需求进行逆置的组合。

void Reverse(DataType A[],int left,int right,int arraysize)//需掌握数组中逆置算法代码,多书写几遍
{
	if(left>=right||rigth>=arraysize)
	return;
	int mid=(left+right)/2;
	for(int i=0;i<=mid-left;i++)
	{
		DataType temp=A[left+i];
		A[left+i]=A[right-i];
		A[right-i]=temo;
	}//需掌握数组中逆置算法代码
void Exchange(DataType A[],int m,int n,int arraysize)
{
	Reverse(A,0,m+n-1,arraysize);
	Reverse(A,0,n-1,arraysize);
	Reverse(A,n,m+n-1,arraysize);//多体会一下如何通过多次逆置交换能够交换前后两部分a1..am b1..bn
}
void left_transfer(DataType A[],int p)
{
	reverse(A,0,n-1,arraysize);
	reverse(A,n-1-p,n-1,arraysize);
	reverse(A,0,n-2-p,arraysize);//逆置算法可以多种方法,结果一样即可
}
}

**标志性语句:**合并,两个有序顺序表,二路归并

bool Merge(SqList &A,SqList &B,SqList &C)//将两个有序的顺序表合并成一个顺序表
{
	if(A.length+B.length>C.maxsize)
	return false;
	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
		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;
    return true;	
}
//找到两个序列的中位数,可以先合并,然后直接输出就行。
int midnumber(SqList A,SqList B)
{
    SqList C[A.length+B.length+10];
    Merge(A,B,C);
    if(C.length%2==0)
    return C.length/2;
    else return C.length/2+1;
}

标志性语句:辅助数组,可以将某整数值录入数组,并后续统计数组

int findmissMin(int A[],int n)//找到最小整数
{
	int i,*B;
	B=(int*)malloc(sizeof(int)*n);//分配数组的语句
	for(i=0;i<n;i++)
	B[i]==0;//辅助数组记得初始化
	for(i=0;i<n;i++)
	{if(A[i]>0&&A[i]<n)//注意理解A[i]的取值可以大于n,为了代码的健壮性,一定要
	    B[A[i]]=1;
	}
	for(i=1;i<n;i++)
	{	
		if(A[i]==0return i;
	}
}

int major(int A[],int n)//找到大于n/2的相同的数
{
	int*B;
	B=(int*)malloc(sizeof(int)*n)
	for(int i=0;i<n;i++)
	B[i]=0;
	for(int j=0;j<n;j++)
	{
	    B[A[j]]++;
	}
	for(int k=0;k<n;k++)
	{
		if(B[k]>n/2return k;
	}
	return -1;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值