这种排序算法的复杂性是什么?使用相同的缺点是什么?

时间:2017-07-25 15:03:05

标签: sorting big-o binary-search-tree

排序算法可以描述如下:

1。从数组数据创建二进制搜索树。

(对于多次出现,当前节点的增量发生变量)

2。以顺序方式遍历BST。

(Inorder遍历将返回数组中元素的排序顺序。)

第3。在inorder遍历中的每个节点处,用当前节点值覆盖当前索引(索引从0开始)的数组元素。

这是一个相同的Java实现:

节点类的结构

class Node {
    Node left;
    int data;
    int occurence;
    Node right;
}

inorder功能 (返回类型是int,只是为了在每次调用时获得正确的索引,它们不起作用)

public int inorder(Node root,int[] arr,int index) {
    if(root == null) return index;
    index = inorder(root.left,arr,index);
    for(int i = 0; i < root.getOccurence(); i++)
        arr[index++] = root.getData();
    index = inorder(root.right,arr,index);
    return index;
}

主要()

public static void main(String[] args) {
    int[] arr = new int[]{100,100,1,1,1,7,98,47,13,56};
    BinarySearchTree bst = new BinarySearchTree(new Node(arr[0]));
    for(int i = 1; i < arr.length; i++)
        bst.insert(bst.getRoot(),arr[i]);
    int dummy = bst.inorder(bst.getRoot(),arr,0);
    System.out.println(Arrays.toString(arr));
}

我知道,空间复杂性很糟糕,但除非将这种排序用于极其庞大的数据集,否则它不应该是一个大问题。但是,正如我所看到的,时间复杂性O(n)是不是? (来自BST的插入和检索是O(log n),并且每个元素被触摸一次,使其成为O(n))。如果我错了,请纠正我,因为我还没有好好研究Big-O。

2 个答案:

答案 0 :(得分:0)

假设插入的摊销(平均)复杂度为O(log n),则N插入(构建树)将给O(log(1) + log(2) + ... + log(N-1) + log(N) = { {1}} = O(log(N!))斯特林定理)。要回读已排序的数组,请执行按顺序深度优先遍历,它会访问每个节点一次,因此O(NlogN)。将这两者结合起来O(N)

但是,这要求树始终平衡!对于最基本的二叉树,一般情况并非如此,因为插入不会检查每个子树的相对深度。有许多自我平衡的变体 - 最着名的两个是红黑树 AVL树。然而,平衡的实施非常复杂,并且通常会导致实际性能中更高的常数因素。

答案 1 :(得分:0)

  

目标是实现一个O(n)算法,用n [1,n ^ 2]范围内的每个元素对n个元素的数组进行排序

在这种情况下,Radix排序(计数变化)将是O(n),采用固定数量的通过(logb(n ^ 2)),其中b是用于该字段的“基数”,并且ba函数为n,例如b == n,它需要两次传递,或者b == sqrt(n),它需要四次传递,或者如果n足够小,b == n ^ 2,它将需要两次传递可以使用一次通过和计数排序。 b可以向上舍入到2的下一个幂,以便用二进制移位和二进制和替换除法和模。基数排序需要O(n)额外空间,但二叉树的链接也是如此。