zl程序教程

您现在的位置是:首页 >  其他

当前栏目

「二叉搜索树 / set / 朝鲜树 / 替罪羊树」快速排序

搜索set排序 快速 二叉
2023-09-27 14:27:46 时间

 要求

给定n个数,对这n个数进行排序

 

这题当然可以直接调用sort

#include<cstdio>
#include<vector>
#define ll long long
using namespace std;
ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n;
vector<int> a;
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        int x=read();
        a.push_back(x);
    }
    sort(a.begin(),a.end());
    for(vector<int>::iterator i=a.begin();i!=a.end();i++)
        printf("%d ",*i);
    return 0;
}

 

用set实现排序,元素必须无重复

 1 #include<cstdio>
 2 #include<set>
 3 #define ll long long
 4 using namespace std;
 5 ll read()
 6 {
 7     ll x=0,f=1;char ch=getchar();
 8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
10     return x*f;
11 }
12 int n;
13 set<int>st;
14 int main()
15 {    
16     n=read();
17     for(int i=1;i<=n;i++)
18     {
19         int x=read();
20         st.insert(x);
21     }
22     for(set<int>::iterator i=st.begin();i!=st.end();i++)
23         printf("%d ",*i);
24     return 0;
25 }

 

 

用二叉搜索树来排序,但不能通过已经排序好的大数据点

 1 #include<cstdio>
 2 #define ll long long
 3 using namespace std;
 4 ll read()
 5 {
 6     ll x = 0, f = 1; char ch = getchar();
 7     while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
 8     while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
 9     return x * f;
10 }
11 int rt, cnt;    //rt为根节点标号,cnt为当前节点个数
12 int t, n, ans;
13 int v[200005], ls[200005], rs[200005];
14 int insert(int &k, int x)
15 {
16     if (!k)
17     {
18         k = ++cnt;
19         v[k] = x;
20         return k;
21     }
22     if (x < v[k])  insert(ls[k], x);
23     else   insert(rs[k], x);
24     return k;
25 }
26 
27 //中序遍历
28 void dfs(int x)
29 {
30     if (!x)return;
31     dfs(ls[x]);
32     printf("%d ", v[x]);
33     dfs(rs[x]);
34 }
35 int main()
36 {
37     n = read();
38     for (int i = 1; i <= n; i++)
39     {
40         int x = read();
41         insert(rt, x);
42     }
43     dfs(rt);
44     return 0;
45 }

 

可以打乱输入的数据实现深度期望

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #define ll long long
 5 using namespace std;
 6 
 7 ll read()
 8 {
 9     ll x = 0, f = 1; char ch = getchar();
10     while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
11     while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
12     return x * f;
13 }
14 int rt, cnt;
15 int t, n, ans;
16 int v[200005], ls[200005], rs[200005];
17 
18 int insert(int &k, int x)
19 {
20     if (!k)
21     {
22         k = ++cnt;
23         v[k] = x;
24         return k;
25     }
26     if (x < v[k])insert(ls[k], x);
27     else insert(rs[k], x);
28     return k;
29 }
30 void dfs(int x)
31 {
32     if (!x)return;
33     dfs(ls[x]);
34     printf("%d ", v[x]);
35     dfs(rs[x]);
36 }
37 int a[200005];
38 int main()
39 {
40     n = read();
41     for (int i = 1; i <= n; i++)
42     {
43         a[i] = read();
44         swap(a[i], a[rand() % i + 1]);
45     }
46     for (int i = 1; i <= n; i++)
47         insert(rt, a[i]);
48     dfs(rt);
49     return 0;
50 }

 

朝鲜树,当插入超过某个深度时重构整颗树

 1 #include<set>
 2 #include<cmath>
 3 #include<stack>
 4 #include<queue>
 5 #include<cstdio>
 6 #include<vector>
 7 #include<cstring>
 8 #include<cstdlib>
 9 #include<iostream>
10 #include<algorithm>
11 #define mod 1000000
12 #define pi acos(-1)
13 #define inf 0x7fffffff
14 #define ll long long
15 using namespace std;
16 ll read()
17 {
18     ll x = 0, f = 1; char ch = getchar();
19     while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
20     while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
21     return x * f;
22 }
23 bool flag;
24 int rt, cnt;
25 int t, n, ans;
26 int v[200005], ls[200005], rs[200005];
27 int a[200005];
28 
29 int insert(int &k, int x, int depth)
30 {
31     if (depth > 1000)  flag = 1;    //插入某个数时深度大于设定,将重构标志设为true
32     if (!k)
33     {
34         k = ++cnt;
35         v[k] = x;
36         return k;
37     }
38     if (x < v[k])insert(ls[k], x, depth + 1);
39     else insert(rs[k], x, depth + 1);
40     return k;
41 }
42 void dfs(int x)
43 {
44     if (!x)return;
45     dfs(ls[x]);
46     printf("%d ", v[x]);
47     dfs(rs[x]);
48 }
49 
50 //简单重构,甚至没有利用前i个有序
51 void rebuild(int &k, int l, int r)
52 {
53     if (l > r)return;
54     int mid = (l + r) >> 1;
55     k = mid;
56     v[k] = a[mid];
57     rebuild(ls[k], l, mid - 1);
58     rebuild(rs[k], mid + 1, r);
59 }
60 int main()
61 {
62     n = read();
63     for (int i = 1; i <= n; i++)
64         a[i] = read();
65     for (int i = 1; i <= n; i++)
66     {
67         insert(rt, a[i], 0);
68         if (flag)
69         {
70             for (int j = 1; j <= i; j++)  ls[j] = rs[j] = v[j] = 0;
71             rebuild(rt, 1, i);  //对前i个重构
72             flag = 0;
73         }
74     }
75     dfs(rt);
76     return 0;
77 }

 

替罪羊树

通过非旋转的重构实现的二叉平衡树,是朝鲜树的高级版,详情可见https://www.cnblogs.com/lfri/p/10006414.html

 

参考链接:

http://hzwer.com/8016.html

https://baike.baidu.com/item/朝鲜树/17008833