数据结构——实用、常考的几个代码块

合并两升序链表

typedef struct LinkNode{
	int data;
	struct LinkNode* next;
}LinkNode;



//将L2合并到L1中
LinkNode * merge(LinkNode *L1, LinkNode *L2){
	LinkNode *p,*q,*r;
	p = L1->next;
	q = L2->next;
	r = L1;//指向p的前驱,插入的时候用
	while(p != NULL && q != NULL){
		//略过L1中比q小的元素
		if(p -> data <= q->data){
			p = p->next;
			r = r->next;
		}
		//找到第一个比q大的元素
		else{
			//此时r->data <= q->data < p->data
			//将q插到r和p中间
			LinkNode tmp = q->next;
			q->next = p->next;
			r->next = q;
			q = tmp;
		}
	}
	//如果L1已经遍历完了,L2还没,将L2剩余元素拼接到L1后面
	if(q != NULL)
		r->next = q;
	return L1;
}

链表结点的删除(带尾指针)


不单独写函数了,哪里需要往哪贴就行,一般也就一个地方
p指向当前结点,q指向前驱,r
为尾指针

q->next = p->next;
if(p==r) r = q;//防止尾指针被删!!!
free(p);
p = q->next;

头插法逆置链表(带头结点)

建议动手根据代码复现一下过程

LinkNode * Inverse(LinkNode *L){
	LinkNode *p,*r;
	p = L->next;
	while(p != NULL){
		r = p->next;
		p->next = L->next;
		L->next = p;
		p = r;
	}
	return L;
}

找到链表的倒数第k个元素

LinkNode* getNode(LinkNode*h, int k){
	LinkNode *p, *q;
	p=h;
	q=h;//此时若p指向最后一个元素,q指向倒数第一个元素,所以p还要往后移k-1个
	for(int i=0; i<k-1; i++){
		if(p -> next !=NULL) p=p->next;
		else return false;
	}
	//退出循环时,p和q相距k-1
	//将p移到最后
	while(p->next){
		p = p->next;
		q = q->next;
	}
	return q;
}

快排

int Partition(int A[], int low, int high){
	int mid = A[low];
	while(low < high){
		//找到后半部分比比中间元素小的,移到前半部分
		while(low < high && A[high] >= mid) high--;//注意判断条件是大于等于!!
		A[low] = A[high];
		//找到前半部分比比中间元素大的,移到后半部分
		while(low < high && A[low] <= mid) low++;
		A[high] = A[low];
	}
	//退出时low = high ,指向mid应该放的位置
	A[low] = mid;
	return low;
}

//递归log2N次
void Qsort(int A[], int low, int high){
	if(low < high){
		int mid = Partition(A, low, high);
		//继续排序下半部分
		Qsort(A, low, mid-1);
		//继续排序上半部分
		Qsort(A, low+1,high);
	}
}

时间复杂度最好Nlog2N,平均Nlog2N,最坏n^2(初始有序)
空间复杂度log2N,递归栈占用

快排改造——用于找到第k小(大)的数

以找到第k小为例

int Partition(int A[], int low, int high){
	int mid = A[low];
	while( low < high ){
		while( low < high && A[high] >= mid) high--;
		A[low] = A[high];
		while( low < high && A[low] <= mid) low++;
		A[high] = A[low];
	}
	A[low] = mid;
	return low;
}

int Qsort(int A[], int low, int high, int k){
	//i,j 分别代表当前排序的下界和上界
	int i=low, j = high -1;
	//mid为中枢元素的最终位置
	int mid = -1;
	while( i<j ){
		mid = Partition(A, i, j);
		//所求元素在下半部分,更改上限
		if(mid > k-1) j = mid - 1;
		//所求元素在上半部分,更改下限
		else if(mid < k-1) i = mid + 1;
		//找到所求元素,返回
		else return A[mid];
	}
	//退出时已经有序
	return A[k-1];
	
}

时间复杂度O(n),空间复杂度O(1)

各种存储结构定义

下面主要是几个不太熟悉的

①二叉树的链式存储

typedef struct BiNode{
	int data;
	struct BiNode *left, *right;
}BiNode;


【注】变量名称以具体题目为准

②图的邻接表存储

//边表结点
typedef struct ArcNode{
	int adjvex;
	struct ArcNode *nextarc;
	//权值int weight;
}ArcNode;

//顶点表结点
typedef struct VNode{
	Elemtype data;
	ArcNode* firstarc;
}VNode;

typedef struct ALGraph{
	//所有顶点存在一维数组中
	VNode vertexes[Maxsize];
	int vexnum, arcnum;
}AlGraph;

还有数组的遍历、二叉树的前、中后序遍历啥的,比较简单就不写了

复习自用,纯手打,有错请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值