Ky Codes Records

一、 排序

快排

时间复杂度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.空二叉树也平衡
是否为平衡二叉树
是否为完全二叉树?

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值