一、 排序
快排
时间复杂度O(nlogn),空间复杂度O(logn)
#include<bits/stdc++.h>
int a[15]={4,1,2,5,7,8,9,6,3,10};
void qs(int a[],int s,int e)
{
int l=s,r=e;
if(l>=r)//递归结束条件
return ;
int mid=a[l];
//排序
while(l<r){
while(l<r&&a[r]>=mid){
r--;
}
a[l]=a[r];
while(l<r&&a[l]<=mid)
l++;
a[r]=a[l];
}
a[l]=mid;//排完序后基准元素放中间
qs(a,s,l);//排左半部分
qs(a,l+1,e);//排右半部分
}
int main()
{
qs(a,0,9);
for(int i=0;i<9;i++)
{
printf("%d ",a[i]);
}
return 0;
}
使用划分函数找到数组第k小(第k大)的元素
空间复杂度O(1),时间复杂度O(n)
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
int a[15]= {5,8,7,4,1,3,6,2,9};
int k;
int huafen(int a[],int s,int e)
{
int l=s,r=e;
int mid=a[l];
/* if(l>=r)
return 0;*/
while(l<r)
{
while(l<r&&a[r]>=mid)
r--;
a[l]=a[r];
while(l<r&&a[l]<=mid)
l++;
a[r]=a[l];
}
a[l]=mid;
return l;//基准元素排序后的中间位置
}
int func(int a[],int len,int k)
{
int left=0,right=len-1,m=0;
while(1)
{
m=huafen(a,left,right);
if(m==k-1)
break;
else if(m>k-1)
right=m-1;
else if(m<k-1)
left=m+1;
}
return a[k-1];
}
int main()
{
int n;
while(~scanf("%d",&n))
{
k=n;
int k1=func(a,9,n);
printf("%d\n",k1);
}
return 0;
}
归并排序
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
int a[100];
void merge(int a[],int l,int r,int mid)
{
int b[100];
int i,j,k = 0;
for(i=l,j=mid+1;i <= mid && j <= r;)
{
if(a[i]<=a[j])
b[k++]=a[i++];
else
b[k++]=a[j++];
}
while(i<=mid)
b[k++]=a[i++];
while(j<=r)
b[k++]=a[j++];
int t=0;
for(int i=l;i<=r;i++)
a[i]=b[t++];
}
void merge_sort(int a[],int l,int r)
{
if(l>=r)
return ;
int mid=(l+r)/2;
merge_sort(a,l,mid);
merge_sort(a,mid+1,r);
merge(a,l,r,mid);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
merge_sort(a,0,n-1);
for(int i=0; i<n; i++)
printf("%d ",a[i]);
return 0;
}
二、链表
定义单链表结点
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
求单链表的长度
int len(LinkList L)
{
int l=0;
LNode *p=L->next;
while(p!=NULL)
{
l++;
p=p->next;
}
printf("%d\n",l);
}
求单链表的中间结点
LNode *findmid(LinkList L)
{
int l=0;
LNode *p=L->next;
while(p!=NULL)
{
l++;
p=p->next;
}
int s=0;
p=L->next;
while(p!=null)
{
s++;
if(s==l/2)
break;
p=p->next;
}
return p;
}
按关键字条件查找+删除
void deletex(LinkList L,int x)
{
LNode *pre=L;//pre指向p的前驱节点
LNode *p=pre->next;//p指向后一个结点
while(p!=NULL)
{
if(p->data==x)
{
LNode *q=p;//删除并释放值为x的结点
p=p->next;//p指向后一个结点
pre->next=p;//修改前驱结点的next指针
free(p);
}
else
{
pre=p;//pre p后移
p=p->next;
}
}
}
按关键字查找+插入
void insertx(LinkList L,int x)
{
LNode *pre=L;
LNode *p=pre->next;
while(p!=NULL)
{
if(p->data>x)
break;
else
{
pre=p;
p=p->next;
}
}
LNode *q=(LNode *)malloc(sizeof(LNode));
q->data=x;
q->next=p;
pre->next=q;
}
单链表原地逆置
头插法的链表是逆序的 ,尾插法的链表是顺序的
void ListReverse(LinkList L)
{
//分配一个辅助头结点
LinkList head=(LNode *)malloc(sizeof(LNode));
head->next=NULL;
while(L->next!=NULL)
{
LNode *p=L->next;//顺序拆结点
L->next=L->next-next;
p->next=head->next;//头插法
head->next=p;
//taila->next=p; 尾插法
// p->next=NULL;
// taila=p;
}
L->next=head->next;
free(head);
}
三、二叉树
二叉树的结点定义(链式存储)
typedef struct BiTNode{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
先序遍历 根左右
void pre(BiTree root)
{
if(root==NULL )
return;
visit(root);
pre(root->lchild);
pre(root->rchild);
}
中序遍历 左根右
void mid(BiTree root)
{
if(root==NULL )
return;
mid(root->lchild);
visit(root);
mid(root->rchild);
}
后序遍历 左右根
void Beh(BiTree root)
{
if(root==NULL )
return;
Beh(root->lchild);
Beh(root->rchild);
visit(root);
}
层序遍历
求二叉树的高度
int h=0;//全局变量记录树高
void pre(BiTree T,int n)
{
if(root==NULL)
return ;
if(n>h)
h=n;
pre(T->lchild,n+1);
pre(T->rchild,n+1);
}
树的高度等于左右子树中更高的高度+1
int Beh(BiTree T)
{
if(T==null)
return 0;
int left=Beh(T->lchild);
int right=Beh(T->rchild);
return max(left,right)+1;
}
二叉树的宽度
即结点最多的某层有多少个结点
int width[maxx];
void pre(BiTree T,int level)
{
if(T=NULL)
return;
width[level]++;//累加该层结点的个数
pre(T->lchild,level+1);
pre(T->rchild,level+1);
}
void treewidth(BiTree T)
{
for(int i=0;i<Max;i++)
width[i]=0;
pre(T,0);//先序遍历,统计各层结点
int maxwidth=0;
for(int i=0;i<Max;i++)
{
if(width[i]>maxwidth)
maxwidth=width[i];
}
return maxwidth;
}
二叉树的WPL(所有叶节点的带权路径长度之和)
int WPL=0;
int pre(BiTree T,int deep)
{
if(T==NULL)
return 0;
if(T->lchild==NULL&&T->rchild==NULL)
return WPL += (T->weight *deep);
pre(T->left, deep + 1);
pre(T->right, deep + 1);
return WPL;
}
int WPL =0; //全局变量
int Beh(BiTree T,int deep)
{
if(T==NULL)
return 0;
if (T->lchild==NULL&&T->rchild==NULL)
return WPL += (T->weight *deep);
else
return Beh(T->lchild,deep+1)+Beh(T->rchild,deep+1);
}
判断是否为二叉排序树?
左<=根<=右
true是二叉排序树 false不是
中序遍历递增
判断是否为平衡二叉树?
1.左右子树的高度之差绝对值小于等于1
2.空二叉树的高度为0
3.空二叉树也平衡
是否为完全二叉树?