22222

xxb

顺序表

顺序存储(静态分配)
#define MaxSize 50.   //定义线性表的最大长度
typedef struct{
	ElemType data[MaxSize];  //顺序表的元素
	int length;             //顺序表的当前长度
}SqList;               //顺序表的类型定义 
顺序存储(动态分配)
#define InitSize 100.   //表长度的初始定义
typedef struct{
	ElemType *data;     //指示动态分配数组的指针
	int MaxSize,length;  //数组的最大容量和当前个数
}SeqList;               //动态分配数组顺序表的类型定义
插入(在第i个位置插入新元素e)

1<=i<=L.length+1
若i输入不合法,则返回false,表示插入失败。否则,将第i个元素及其后的所有元素依次往后移动一个位置,腾出一个空位置插入新元素e,顺序表长度增加1,插入成功,返回true。
在这里插入图片描述

bool ListInsert(SqList &L,int i,ElemType e){
	if(I<1||i>L.length+1) return false;  //判断i的范围是否有效
	if(L.length>=MaxSize) return false;  //当前存储空间已满,不能插入
	for(int j=L.length;j>=i;j-) L.data[j]=L.data[j-1];//将第i个元素及之后的元素后移
	L.data[i-1]=e;   //在位置i处放入e
	L.length++;      //线性表长度加1
	return true}
删除

删除顺序表中第i个位置的元素, 用引用变量e返回。若i的输入不合法,则返回false;否则,将被删元素赋给引用变量e,并将第i+1个元素及其后的所有元素依次往前移动一个位置,返回true
第i个位置,也就i-1坐标。把第i个坐标赋值给i-1

bool ListDelete(SqList &L,int i,Elemtype &e){
	if(i<1||i>L.length) return false;  //判断i的范围是否有效
	e=L.data[i-1];    //将被删除的元素赋值给e
	for(int j=i;j<L.length;j++) L.data[j-1]=L.data[j]; //将第i个位置后的元素前移
	L.length—-;  //线性表长度减1
	return true;
}
按值查找

在顺序表中查找第一个元素值等于e的元素,并返回其位序

int LocateElem(SqList L,ElemType e){
	int i;
	for(int i=0;i<L.length;i++)
		if(L.data[i]==e)
			return i+1;    //下标为i的元素值等于e,返回其位序i+1
	return 0;              //推出循环,说明查找失败
}
1、删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补。若顺序表为空,则显示出错信息并推出运行
bool Del(SqList &L,ElemType &value){
	//删除顺序表L中最小值元素结点,并通过引用型参数value返回其值
	//若删除成功,则返回true,否则返回false
	if(L.length==0) return false;  //表空,中止操作返回
	value=L.data[0];
	int pos=0;    //假定0号元素的值最小
	for(int i=1;i<L.length;i++) //循环,寻找具有最小值的元素 
		if(L.data[i]<value){  //让value记忆当前具有最小值的元素
			value=L.data[i];
			pos=i;
		}
	L.data[pos]=L.data[L.length-1]; //空出的位置由最后一个元素填补
	L.length—-;
	return true;     //此时,value即为最小值

}
2、元素逆置

i>=j 时候停止

void Reverse(SqList &L,int from,int to){
	ElemType temp;  //辅助变量
	for(i=from,j=to;i<j;i++,j—-){
		temp=L.data[i];     //交换
		L.data[i]=L.data[j];
		L.data[j]=temp;
	}
}
3、整体右移动

视为把数组ab转换成数组ba,先将a逆置得到a-1b,再将b逆置得到a-1b-1,最后将整个逆置(a-1b-1)-1=ba。

void RightMove(SqList &L,int move){
	Reverse(A,0,move-1);
	Reverse(A,move,L.length-1);
	Reverse(A,0,L.length-1);
}
void Converse(int R[],int n,int p){
	Reverse(R,0,p-1);
	Reverse(R,p,n-1);
	Reverse(R,0,n-1);
}
4、删除顺序表L中所有值为x的数据元素

用k记录顺序表L中不等于x的元素个数(即需要保存的元素个数),边扫描L边统计k,并将不等于x的元素向前移动k个位置,最后修改L的长度

void del(SqList &L,ElemType x){
	//本算法实现删除顺序表L中所有值为x的数据元素
	int k=0;      //记录值不等于x的元素个数
	for(i=0;i<L.length;i++){
		if(L.data[i]!=x){
			L.data[k]=L.data[i];
			k++;      //不等于x的元素增1
		}
	}
}
5、删除值在s-t之间所有元素,若s或t不合理或L为空,显示错误信息并退出运行

有序表(要求s<t)
先寻找值大于等于s的第一个元素(第一个删除的元素),然后寻找值大于t的第一个元素(最后一个删除的元素的下一个元素),要将这段元素删除,只需将后面的元素前移动。
[s][]….t[],把t后的[]替换[s] ,直到t后的[j]遍历到最后length-1

bool del(SqList &L, ElemType s,ElemType t){
	int i,j;
	if(s>=t||L.length==0) return false;
	for(i=0;i<L.length&&L.data[i]<s;i++);//寻找值>=s的第一个元素
	if(i>=L.length) return false; //所有元素值均小于s,返回
	for(j=i;j<L.length&&L.data[j]<=t;j++);//寻找值>t的第一个元素
	for(;j<L.length;i++,j++) L.data[i]=L.data[j]; //前移,填补被删元素位置
	L.length=i;    //长度是i的长度
	return true;
}

顺序表(包含s和t,要求s<t)
从前往后顺序扫描顺序表L,用k记录下元素值在s到t之间元素的个数(初始时k=0)对于当前扫描的元素,若其值不在s到t之间,则前移k个位置;否则执行k++。
0123456789—>012[3]456[7]89

bool Del(SqList &L,ElemType s,ElemType t){
	int i,k=0;
	if(L.length==0||s>=t) return false; //线性表为空或s、t不合法,返回
	for(i=0;i<L.length;i++){
		if(L.data[i]>=s&&L.data[i]<=t) k++;
		else L.data[i-k]=L.data[i]; //当前元素前移k个位置
	}//for
	L.length-=k;       //长度减小
	return true;
}
6、有序顺序表中删除所有值重复的元素,使表中所有元素的值均不同

有序顺序表值相同的元素一定在连续的位置上,用类似于直接插入排序的思想,初识时将第一个元素视为非重复(不相同)的有序表。之后依次判断if后面的元素是否于前面非重复有序表的最后一个元素相同[不用管] 若相同,则继续向后判断[++i] 若不同,则插入前面的非重复有序表的最后,直到判断到表尾

bool Del(SeqList &L){
	if(L.length==0) return false;
	int i,j;         //i存储第一个不相同的元素,j为工作指针
	for(i=0,j=1;j<L.length;j++)  //j从1遍历到尾
		if(L.data[i]!=L.data[j])    //查找下一个与上个元素值不同的元素
			L.data[++i]=L.data[j];   //找到后,将元素前移
	L.length=i+1;
	return true;
}
7、将有序顺序表A与B合并为一个新的有序顺序表C

按顺序不断取下两个顺序表表头较小的结点存入新的顺序表中。看看哪个表还有剩余,将剩下的部分加到新的顺序表后面

bool Merge(SeqList A,SeqList B,SeqList &C){
	if(A.length+B.length>C.maxSize) return false;//大于顺序表的最大长度
	int i=j=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;     //记得写length
	return true;	
}
8、已知A[m+n]中依次存放两个线性表。函数将数组两个顺序表的位置互换。(a1,a2,a3,am,b1,b2,bn)—>(b1,b2,bn,a1,a2,a3,am)

先全部元素原地逆置,再对前n个元素和后m个元素分别使用逆置算法
参考2、3、

9、递增有序顺序表,查找数值为x的元素,若找到,则将其于后继元素位置相交换,若找不到,则将其插入表中并使表中元素仍递增有序

折半查找块,mid小+大-

void Findx(SqList L,isn’t x){
	int low=0,high=l.length-1,mid; //low和high指向顺序表下届和上届的下标
	while(low<=high){ //low>high的时候跳出循环
		mid=(low+high)/2;   //找中间位置
		if(L.data[mid]==x) break;  //找到x退出循环
		else if(L.data[mid]<x) low=mid+1;  //到中点mid右半部去查
		else high=mid-1;  //到中点mid的左半部曲查
	}
	//下面两个if语句只会执行一个
	if(L.data[mid]==x&&mid!=n-1){
		t=L.data[mid];L.data[mid]=L.data[mid+1];L.data[mid+1]=t;
	}
	if(low>high){ //查找失败,插入数据元素x
		for(i=n-1;i>high;i—-) L.data[i+1]=L.data[i]; //后移元素
		L.data[i+1]=x;     //插入x
	}                      //结束插入
}
10、第「L/2 个位置是中位数。有两个等长升序序列A B,找出A B的中位数。

从头到尾一共len个数,这个时候两个指针指向的数字较小者即为所求
🌰:(11、13、15、17、19)(2、4、6、8、20)= 11

int midNum(int *a,int *b,int len){
	int i=0,j=0;     //ij分别指向AB
	for(k=0;k<Len-1;k++){     //从头开始便利,走len步
		if(a[i]<b[j]) i++;
		else j++;
	}
	Return (a[i]<b[j])?a[i]:b[i];
}
11、主元素:个数m>n/2 若存在主元素,输出该元素,否则输出-1

1和123456…比较,2和123456…比较

int ZhuYuanSu(int A[],int n){
	for(int i=0;i<n;i++){
		int count=0;
		for(int j=0;j<n;j++){
			if(A[j]==A[i]) count++;
		}
		if(count>n/2) return A[i];
		else count=0;
	}
}

因为主元素的个数大于n/2,如果两个不同的元素两两抵消,那么就不存在主元素,如果没有完全抵消,那么余下的元素可能就是主元素,因此统计钙元素的出现次数,即可判断是否存在主元素

int Majority(int A[],int n){
	int i,c,count=1;    //c用来保存候选主元素,count用来计数
	c=A[0];            //设置A[0]为候选主元素
	for(i=1;i<n;i++)  //查找候选主元素
		if(A[i]==c) 
			count++;      //对A中的候选住元素计数
		else
			if(count>0)   //处理不是候选主元素的情况
				count—;
			else{         //更换候选主元素,重新计数
				c=A[i];
				count=1;
			}
	if(count>0)
		for(i=count=0;i<n;i++)   //统计候选主元素的实际出现次数
			if(A[i]==c) 
				count++;
	if(count>n/2) return c;     //确定候选主元素
	else return -1;           //不存在主元素
}
12、找出数组中未出现的最小正整数

法一:1->2->3->4一直找到->n,暴力搜寻,最小正整数是1,从1开始增加,每个正整数都在数组中找是否有这个数,没有的话输出其值。时间复杂度O(n2) 空间复杂度O(n)
递归

int findMisssMin(int A[],int len){
	int n=1;  //先找1
	for(int i=0;i<len;i++){ 
		if(a[i]==n){//有1了
			n++;//找2
			return findMissMin(n,a,length);
		}
	}
	return n;
}

王道:动态数组

int findMissMin(int A[],int n){
	int I,*B;
	B=(int *)malloc(sizeof(int)*n); //分配空间
	memset(B,0,sizeof(int)*n);    //赋初值为0
	for(i=0;i<n;i++)
		if(A[i]>0&&A[i]<=n)      //若A[i]的值介于1~n,则标记数组B
			B[A[i]-1]=1;
	for(i=0;i<n;i++)//扫描数组B,找到目标值
		if(B[i]==0)break;
	return i+1;               //返回结果
}
13、三元组(a,b,c) 距离D=|a-b|+|b-c|+|c-a| 。有三个非空整数升序集合S1.S2.S3. 计算并输出最小距离。例:s1={-1,0,9} s2={-25,-10,10,11} s3={2,9,17,30,41},最小距离为2,相应的三元组为(9,10,9)

暴力,三个for求所有的D,找最小的D


若大小为abc,中间b在哪都无关,D总是(最大-最小)乘2 。
取出一个标杆D。假设由小到大abc:
若c变大D变大
若b移到ac之间不变,若b移到比c大,则D变大。
若a变大到a,D变小。若a变大到c是有可能大。
综上,移动最小的那个数。

#define INT_MAX 0x7fffffff //7个f
int abs_(int a){ //	计算绝对值
	if(a<0) return -a;
	else return a;
}
bool xls_min(int a,int b,int c){ //a是否是三个数中最小的
	if(a<=b&&a<=c) return true;
	return false;
}
int findMinofTrip(int A[],int n,int B[],int m,int C[],int p){
	//D_min用于记录三元组的最小距离,初值赋为INT_MAX
	int i=0,j=0,k=0,D_min=INT_MAX,D;
	while(i<n&&j<m&&k<p&&D_min>0){
		D=abs_(A[i]-B[j])+abs_(B[j]-C[k])+abs_(C[k]-A[i]);//计算D
		if(D<D_min) D_min=D;    //更新D
		if(xls_min(A[i],B[j],C[k])) i++;  //更新a
		else if(xls_min(B[j],C[k],A[i]) j++; 
		else k++;
	}
	return D_min;
} 

链表

❤️2012真题:单链表的定义
typedef struct LNode{   //定义单链表结点类型
	ElemType data;       //数据域
	struct LNode *next;    //指针域
}LNode,*LinkList;
头插法建立单链表

s是新结点1⃣️给s赋值 2⃣️(s后)s的next为L的next 3⃣️(s前)L的next为s 🈴️最后是return L

LinkList List_HeadInsert(LinkList &L){
	LNode *s;int x;
	L=(LNode*)malloc(sizeof(LNode));  
	L->next=NULL;
	scanf(%d”,&x);
	while(x!=9999){
		s=(LNode*)malloc(sizeof(LNode));
		s->data=x;
		s->next=L->next;  //核心
		L->next=s;       //核心
		scanf(%d”,&x); 
	}
	return L;
}
尾插法建立单链表

s是新结点 1⃣️给s赋值 2⃣️r的next为s 3⃣️r变为s 🈴️最后是r->next=NULL;return L;

LinkList List_TailInsert(LinkList &L){  
	int x;
	L=(LNode*)malloc(sizeof(LNode));//头结点
	LNode *s,*r=L;   //r为表尾指针
	scanf(%d”,&x);
	while(x!=9999){
		s=(LNode*)malloc(sizeof(LNode));//新结点
		s->data=x;
		r->next=s;     //核心
		r=s;           //核心
		scanf(%d”,&x);
	}
	r->next=NULL;
	return L;
}
按序号查找结点值

在单链表中第一个结点出发,顺指针next域逐个往下搜索,直到找到第i个结点为止,否则返回最后一个结点指针域NULL。
注意用p保留头结点!!!注意是j<i !!

LNode * GetElem(LinkList L,int i){
	int j=1;    //计数
	LNode *p=L->next; //头结点指针赋给p
	if(i==0) return L;  //若i=0.则返回头结点
	if(i<1)return NULL; //若i无效,则返回NULL
	while(p&&j<i){   //从第1个结点开始找,查找第i个结点
		p=p->next;
		j++;	
	}
	return p;
}
按值查找结点
LNode *LocateElem(LinkList L,ElemType e){
	LNode *p=L->next;  //头指针赋值给p
	while(p!=NULL&&p->data!=e)//只有p还有值且e还没找到
		p=p->next;       //往后走
	return p;
}
插入结点(和头插法差不多,把L换成前驱结点p)
p=GetElem(L,i-1);   //查找插入位置都前驱结点
s->next=p->next;    
p->next=s;

扩展:前插操作 p []
1⃣️(s后)s的next为p的next 2⃣️(s前)p的next为s3⃣️交换p和s的数据

s->next=p->next;     //修改指针域,不能颠倒
p->next=s;
temp=p->data;       //交换
p->data=s->data;
s->data=temp;
删除结点操作(q是工作指针,p是前驱结点)

p [删] 1⃣️q指向被删除结点p->next2⃣️前驱p的next跨过q去到q的next

p=GetElem(L,i-1);   //查找删除位置的前驱结点
q=p->next;           // 1
p->next=q->next;     //2
free(q);    

扩展:删除节点*p的后继结点q
实质:将其后继结点q都值赋予其自身,然后删除后继结点
[p] q —- [q] q —-[q]
1⃣️q初始化 2⃣️p=p下一个数据3⃣️p的next是后继的next

q=p->next;
p->data=p->next->data;
p->next=q->next;
free(q);
双链表

定义

typedef struct DNode{    //定义结点类型
	ElemType data;      //数据域
	strict DNode *prior,*next;  //前驱和后继结点
}DNode,*DLinkList;

插入(将结点s插入到结点p之后)
12步必须在4步之前!!!

s->next=p->next;  //1
p->next->prior=s;  //2
s->prior=p;     //3
p->next=s;      //4

删除

p->next=q->next;
q->next->prior=p;
free(q);
1、不带头节点,删除所有值为x的结点

L —> [p] —> p L —> L

void Del(LinkList &L,ElemType x){
	//递归实现在单链表L中删除值为x的结点
	LNode *p;   //p指向待删除结点
	if(L==NULL) return;  //递归出口
	if(L->data==x){ //若l所指的结点为x
		p=L;                   //核心
		L=L->next;             //核心
		free(p);               //核心
		Del(L,x);  //递归调用
	}else{    //若L所指结点的值不为x
		Del(L->next,x); //递归调用
	}
}
2、带头节点,删除所有值为x的结点,值为x的结点不唯一

pre p —> pre q p —> pre [q] p —> pre p

//法一:用p从头到尾扫描单链表,pre指向*p的前驱结点。若p所指结点的值为x,则删除,并让p移向下一个结点,否则让pre、p指针同步后移一个结点。
void Del(LinkList &L,ElemType x){
	LNode *p=L->next,*pre=L,*q; //置p和pre的初始值
	while(p!=NULL){
		if(p->data==x){
			q=p;        //q指向代删除结点p
			p=p->next;     //p向后走
			pre->next=p;   //删除*q结点
			free(q);       //释放*q结点多空间
		}else{
			pre=p;        //先移pre
			p=p->next;    //再移p
		}
	}
}

//法二:尾插法建立单链表,用p指针扫描L的所有结点,当其值不为x时,将其连接到L之后,否则将其释放
// r p -> r [q] p
void del(LinkList &L,ElemType x){
	LNode *p=L->next,*r=L,*q; //r指向尾结点,初值为头结点
	while(p!=NULL){
		if(p->data!=x){
			r->next=p;
			r=p;         //r往后走
			p=p->next;   //p往后走
		}else{
			q=p;       //核心
			p=p->next;  //核心 
			free(q);  //核心
		}
	}
	r->next=NULL;  //插入结束后置尾结点指针为NULL
}
3、带头节点,从尾到头反向输出每个结点的值

l的next如果等于null了就退出执行print(L->data),

 void R_Print(LinkList L){
	if(L->next!=NULL) R_Print(L->next); //递归
	if(L!=NULL) print(L->data);     //输出函数
}
void R_Ignore_Head(LinkList L){
	if(L!=NULL) R_Print(L->next);
}
❤️真题:data|link 头指针list,查找链表倒数第k个位置上的结点,成功1否则0

这里

4、带头节点,删除一个最小值结点
LinkList Delete_Min(LinkList &L){
	LNode *pre=L,*p=pre->next;   //p为工作指针,pre前驱
	LNode *minpre=pre,*minp=p;  //保存最小值结点及前驱
	while(p!=NULL){
		if(p->data<min->data){
			min=p;       //找到比之前找到的最小值结点更小的结点
			minpre=pre;
		}
		pre=p;    //继续扫描下一个结点
		p=p->next;
	}
	minpre->next=minp->next; //删除最小值结点
	free(minp);
	return L;
}
❤️2012真题:5、带头节点,就地逆置(空间复杂度0(1))🌟

L->NULL p->node2->node3 —》L->p->NULL r->node3

//头插法
LinkList Reverse(LinkList L){
	LNode *p,*r;   //p为工作指针,r为p的后继,以防断链
	p=L->next;      //从第一个元素结点开始//1
	L->next=NULL;
	while(p!=NULL){    //依次将元素结点摘下
		r=p->next;        //暂存p的后继 1
		p->next=L->next;  //(p)先连后。将p结点插入到头结点之后
		L->next=p;        //(p)再连前
		p=r;
	}
	return L;
}
6、带头节点,使其元素递增有序

直接插入排序算法的思想,先构成只含一个数据结点的有序单链表,依次扫描单链表中剩下的结点p(直至p==NULL为止),在有序表中通过比较查找插入p的前驱结点pre,然后将p插入到*pre之后
L—>p—>r—>node3–>node4–>node5
L—>p—>NULL. r—>node3–>node4–>node5
L—>node1–>NULL. p->node3–>node4–>node5

void Sort(LinkList &L){
	LNode *p=L->next,*pre;
	LNode *r=p->next;       
	p->next=NULL;
	p=r;
	while(p!=NULL){
		r=p->next;
		pre=L;
		while(pre->next!=NULL&&pre->next->data<p->data)
			pre=pre->next; 
		p->next=pre->next;
		pre->next=p;
		p=r;
	}
}
7、带头节点,无序,删除表中所有介于给定的两个值(作为函数参数)之间的元素的元素(若存在)
void del(LinkList L){


}
8、两个单链表,找出公共节点
9、带头节点,递增次序输出单链表各结点的数据元素
10、带头节点,分解为两个带头节点的单链表AB,A中奇数B中偶数,且相对顺序不变
11、带头节点,aaaabbb就地拆分为为两个链表aaaa、bbbb(头插法)
LinkList DisCreat(LinkList &A){
	LNode *B=(LNode*)malloc(sizeof(LNode));//创建B表表头
	B->next=NULL;

}
12、递增有序,去掉相同元素,使表中不再重复
13、两个递增,归并为一个按元素值递减,并利用原来两个单链表结点存放归并后的单链表🌟
14、带头节点AB,递增有序,设计从AB中公共元素产生C,要求不破坏AB结点
15、AB两个集合,递增排序,求AB的交集并存放于A中
16、判断B是否是A的连续子序列
17、带头结点,判断循环双链表是否对称
18、循环单链表,链表表头指针h1和h2,将h2链接到h1后,要求链接后的链表仍保持循环链表形式
19、带头结点,循环单链表,结点值是正整数,找出最小值的结点并输出,然后将该结点删除,直到单链表空为止,再删除表头结点
20、带头节点,非循环双向链表,。。。。。。
19、
1、链表-合并排序
void mergelklist(lklist *ha,lklist *hb,lklist *&hc)
{
	lklist *s=hc=0;
	while(ha!=0&&hb!=0){
		if(ha->data<hb->data){ //ha小
			if(s==0) hc=s=ha;
			else{ s->next=ha;s=ha;}
			ha=ha->next;
		}else{
			if(s==0) s->next=hb;
			else  s->next=ha;
		}
	}
	if(ha==0)s->next=hb;
	else s->next=ha;
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DDouble-

你的鼓励是我最大的动力~

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

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

打赏作者

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

抵扣说明:

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

余额充值