2012-10-07 35 views
5

Thứ nhất, đây là mã Shell sắp xếp của tôi (sử dụng Java):Độ phức tạp của thời gian đối với Shell sắp xếp?

public char[] shellSort(char[] chars) { 
    int n = chars.length; 
    int increment = n/2; 
    while(increment > 0) { 
     int last = increment; 
     while(last < n) { 
      int current = last - increment; 
      while(current >= 0) { 
       if(chars[current] > chars[current + increment]) { 
        //swap 
        char tmp = chars[current]; 
        chars[current] = chars[current + increment]; 
        chars[current + increment] = tmp; 
        current -= increment; 
       } 
       else { break; } 
      } 
      last++; 
     } 
     increment /= 2; 
    } 
    return chars; 
} 

này thực hiện đúng Shell sort là (quên cho bây giờ về trình tự khoảng cách hiệu quả nhất - ví dụ, 1,3,7,21. ..)? Tôi hỏi vì tôi đã nghe nói rằng sự phức tạp thời gian tốt nhất cho Shell Sort là O (n). (Xem http://en.wikipedia.org/wiki/Sorting_algorithm). Tôi không thể thấy mức hiệu quả này được nhận ra bởi mã của tôi. Nếu tôi thêm heuristics vào nó, thì yeah, nhưng khi nó đứng, không.

Điều đó đang được nói, câu hỏi chính của tôi bây giờ - Tôi đang gặp khó khăn khi tính toán độ phức tạp thời gian Big O cho việc triển khai sắp xếp Shell của tôi. Tôi xác định rằng vòng lặp ngoài cùng nhất là O (log n), vòng giữa là O (n) và vòng lặp bên trong nhất cũng là O (n), nhưng tôi nhận ra hai vòng bên trong sẽ không thực sự là O (n) - chúng sẽ ít hơn nhiều so với điều này - chúng nên là gì? Bởi vì rõ ràng thuật toán này chạy hiệu quả hơn nhiều so với O ((log n) n^2).

Bất kỳ hướng dẫn nào được đánh giá cao vì tôi rất lạc lõng! : P

+0

Xem [shell-sort-java-example] (http://stackoverflow.com/questions/4833423/shell-sort-java-example) – nawfal

Trả lời

6

Trường hợp xấu nhất trong việc triển khai của bạn là Θ (n^2) và trường hợp tốt nhất là O (nlogn) hợp lý để sắp xếp vỏ.

tốt nhất O trường hợp ε (nlogn):

Các hợp cụ thể nhất là khi mảng đã được sắp xếp. Điều đó có nghĩa là câu lệnh if bên trong sẽ không bao giờ đúng, làm cho vòng lặp bên trong lặp lại một hoạt động thời gian không đổi. Sử dụng các giới hạn mà bạn đã sử dụng cho các vòng lặp khác cho O (nlogn). Trường hợp tốt nhất của O (n) đạt được bằng cách sử dụng một số gia số không đổi.

Điều tồi tệ nhất trường hợp ε O (n^2):

Với trên ràng buộc của bạn cho mỗi vòng bạn sẽ có được O ((log n) n^2) cho trường hợp xấu nhất. Nhưng thêm một biến khác cho kích thước khoảng cách g. Số lượng so sánh/trao đổi cần thiết trong nội bộ hiện tại là < = n/g. Số lần so sánh/trao đổi ở giữa là < = n^2/g. Thêm giới hạn trên của số lần so sánh/trao đổi cho mỗi khoảng cách với nhau: n^2 + n^2/2 + n^2/4 + ... < = 2n^2 ∊ O (n^2). Điều này phù hợp với trường hợp phức tạp tồi tệ nhất được biết đến cho những khoảng trống bạn đã sử dụng.

Điều tồi tệ nhất trường hợp ε Ω (n^2):

Cân nhắc mảng nơi mà tất cả các yếu tố thậm chí vị trí lớn hơn mức trung bình. Các yếu tố kỳ lạ và thậm chí không được so sánh cho đến khi chúng tôi đạt đến số gia tăng cuối cùng 1. Số lần so sánh/trao đổi cần thiết cho lần lặp cuối cùng là Ω (n^2).

+1

Số trường hợp so sánh xấu nhất được sử dụng bởi shellsort không phải lúc nào cũng là bậc hai trong n. Với gia số 3x + 1, nó là O (N^3/2) và với chuỗi của sedgewick là O (N^4/3). Tuy nhiên đối với chuỗi được sử dụng trong đoạn mã trên, nó chắc chắn là bậc hai. xem http://en.wikipedia.org/wiki/Shellsort#Gap_sequences –

+0

tài liệu bài giảng của tôi nói rằng thời gian chạy nổi tiếng nhất là O (n^1.5). 'được biết' bởi vì phân tích vẫn chưa hoàn thành cho đến ngày nay. – Gewure

Các vấn đề liên quan