Sorting 这种排序算法的复杂度是多少?使用相同的工具有什么缺点?

Sorting 这种排序算法的复杂度是多少?使用相同的工具有什么缺点?,sorting,big-o,binary-search-tree,Sorting,Big O,Binary Search Tree,排序算法可以描述如下: 1。从数组数据创建二进制搜索树。 (对于多个事件,增加当前节点的事件变量) 2。以有序方式遍历BST。 (按顺序遍历将返回数组中元素的排序顺序) 3。在顺序遍历的每个节点上,用当前节点值覆盖当前索引(索引从0开始)处的数组元素。 下面是同样的Java实现: 节点类的结构 class Node { Node left; int data; int occurence; Node right; } 有序函数 (返回类型为int只是为了在每次调

排序算法可以描述如下:

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

(对于多个事件,增加当前节点的事件变量)

2。以有序方式遍历BST。

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

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

下面是同样的Java实现:

节点类的结构

class Node {
    Node left;
    int data;
    int occurence;
    Node right;
}
有序函数 (返回类型为int只是为了在每次调用时获得正确的索引,它们没有其他用途)

public int-inoder(节点根,int[]arr,int-index){
if(root==null)返回索引;
索引=索引(root.left,arr,index);
对于(int i=0;i
main()

publicstaticvoidmain(字符串[]args){
int[]arr=新的int[]{100100,1,1,1,7,98,47,13,56};
BinarySearchTree bst=新的BinarySearchTree(新节点(arr[0]);
对于(int i=1;i
我知道,空间的复杂性很糟糕,但除非排序用于一个非常庞大的数据集,否则它不应该是一个大问题。然而,在我看来,时间复杂性不是O(n)吗?(从BST的插入和检索是O(logn),每个元素被触摸一次,使其成为O(n))。如果我没有很好地研究Big-O,请纠正我的错误。

假设插入的摊销(平均)复杂度是
O(log n)
,那么
n
插入(树的构造)将给出
O(log(1)+log(2)+log(n-1)+log(n)
=
O(log(n!)
=
O(NlogN)
(斯特林定理)。要读回排序后的数组,请执行按顺序的深度优先遍历,该遍历访问每个节点一次,因此是
O(N)
。将这两个遍历组合在一起可以得到
O(NlogN)

然而,这要求树始终保持平衡!对于最基本的二叉树,通常情况下不会如此,因为插入不会检查每个子树的相对深度。有许多变体是自平衡的-最著名的两个是红黑树和AVL树。然而,平衡的实现是快速的te非常复杂,通常会导致实际性能中更高的常数因子。

假设插入的摊销(平均)复杂度为
O(log n)
,那么
n
插入(树的构造)将给出
O(log(1)+log(2)+…+log(n-1)+log(n)
=
O(log(n!)
=
O(log(n!)
(斯特林定理)。要读回排序后的数组,请执行按顺序的深度优先遍历,该遍历访问每个节点一次,因此是
O(N)
。将这两个遍历组合在一起可以得到
O(NlogN)

然而,这要求树始终保持平衡!对于最基本的二叉树,通常情况下不会如此,因为插入不会检查每个子树的相对深度。有许多变体是自平衡的-最著名的两个是红黑树和AVL树。然而,平衡的实现是快速的te非常复杂,在实际性能中通常会导致更高的常数因子

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

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

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


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

很好的解释!谢谢你这么快的回答。我怎么能接受这个答案作为问题的解决方案?明白了!+1的简洁解释。很好的解释!谢谢你这么快的回答。我怎么能接受这个答案作为问题的解决方案?明白了!+1的简洁解释。我如果您的目标是在O(N*log(N))时间内对数组进行排序,那么您已经可以使用快速排序或合并排序来更好地利用空间,并且您可以从数组->数组而不是数组->树进行映射。@DougCoburn实际上的目标是实现一个O(N)算法来对N个元素的数组进行排序,每个元素的范围为[1,N^2]。我很确定没有O(n)排序算法。在这些约束条件下。@DougCoburn请查看下面用户rcgldr的答案。我目前正在阅读Geeksforgek的一篇文章,内容与此类似。如果您的目标是在O(n*log(n))时间内对数组进行排序,那么您已经可以使用快速排序或合并排序来获得更好的结果
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));
}