合并两升序链表
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;
还有数组的遍历、二叉树的前、中后序遍历啥的,比较简单就不写了