Sắp xếp nhị phân trong Python

Sắp xếp chèn nhị phân là một biến thể hiệu quả hơn của Sắp xếp chèn. Trong hướng dẫn này, chúng ta sẽ sắp xếp một mảng với sự trợ giúp của sắp xếp chèn nhị phân

Sắp xếp chèn nhị phân - Giới thiệu cơ bản

Trong sắp xếp chèn nhị phân, tìm kiếm nhị phân được sử dụng để xác định vị trí chính xác để chèn mục đã chọn. Về cơ bản, nó làm giảm số lượng so sánh từ phương pháp sắp xếp chèn thông thường. Chúng ta phải xác định đúng vị trí của phần tử đang được xem xét trong Sắp xếp Chèn. Số lượng so sánh sẽ giảm nếu chúng ta sử dụng Tìm kiếm nhị phân cho chức năng tìm kiếm này. Do đó, Sắp xếp chèn nhị phân sử dụng tìm kiếm nhị phân trong mỗi lần lặp lại để xác định vị trí chính xác để chèn mục đã chọn

thuật toán

Đến bây giờ, chúng ta đã hiểu sơ bộ về cách thực hiện sắp xếp cơ số. Để hiểu rõ hơn, hãy đi sâu vào thuật toán, sau đó là mã

  1. Tạo hàm binary_insertionSort chấp nhận danh sách làm đầu vào
  2. Tạo một vòng lặp với biến vòng lặp i đếm từ 1 đến độ dài của danh sách – 1 trong hàm
  3. Đặt tạm thời thành giá trị của phần tử tại chỉ mục i
  4. Gọi nhị phân_search
  5. Đặt pos++ giá trị trả về của lệnh gọi trên
  6. Từ chỉ mục pos + 1 đến i chuyển tất cả các mục về một nơi
  7. đặt alist[pos] thành tạm thời
  8. Để tìm một khóa trong danh sách giữa các chỉ mục bắt đầu và kết thúc – bao gồm 1 – một hàm sử dụng tìm kiếm nhị phân
  9. Nếu không tìm thấy khóa, chỉ mục của phần tử nhỏ nhất nhỏ hơn khóa được trả về
  10. Nếu khóa nhỏ hơn phần tử đầu tiên, nó sẽ trả về -1
  11. Mảng hiện đã được sắp xếp
  12. In mảng

Chương trình sắp xếp chèn nhị phân

Mã nguồn cho chương trình Python thực hiện sắp xếp chèn nhị phân được cung cấp bên dưới. Đầu ra của chương trình được hiển thị bên dưới. Trong chương trình này, người dùng được yêu cầu nhập danh sách và sau đó, dạng sắp xếp của danh sách được nhắc bởi trình biên dịch

def binary_insertionsort[array]:
    for i in range[1, len[array]]:
        temp = array[i]
        pos = binary_search[array, temp, 0, i] + 1
 
        for k in range[i, pos, -1]:
            array[k] = array[k - 1]
 
        array[pos] = temp

def binary_search[array, key, strt, end]:
    if end - strt  key:
        return binary_search[array, key, strt, middle]
    else:
        return middle
 
 #driver code
array = input['Enter the array numbers: '].split[]
array = [int[a] for a in array]
binary_insertionsort[array]
print['The Sorted array is: ', end='']
print[array]


Nhập số mảng. 5 4 3 98 76 97
Mảng được sắp xếp là. [3, 4, 5, 76, 97, 98]

Phần kết luận

Trong hướng dẫn này, chúng tôi đã thực hiện phương thức Sắp xếp chèn nhị phân trong chương trình python để sắp xếp một mảng. Độ phức tạp thời gian của sắp xếp chèn nhị phân là O[log n] và độ phức tạp không gian là O[1]

Mô-đun này cung cấp hỗ trợ để duy trì danh sách theo thứ tự được sắp xếp mà không cần phải sắp xếp danh sách sau mỗi lần chèn. Đối với danh sách dài các mục có thao tác so sánh tốn kém, đây có thể là một cải tiến so với cách tiếp cận phổ biến hơn. Mô-đun được gọi vì nó sử dụng thuật toán chia đôi cơ bản để thực hiện công việc của mình. Mã nguồn có thể hữu ích nhất như một ví dụ hoạt động của thuật toán [các điều kiện biên đã đúng. ]

Các chức năng sau đây được cung cấp

chia đôi. bisect_left[a , x , lo=0 , hi=len[a] , * , key=Không có]

Xác định vị trí điểm chèn cho x trong a để duy trì thứ tự đã sắp xếp. Các tham số lo và hi có thể được sử dụng để chỉ định một tập hợp con của danh sách cần được xem xét; . Nếu x đã có trong a, điểm chèn sẽ ở trước [ở bên trái] bất kỳ mục nhập hiện có nào. Giá trị trả về phù hợp để sử dụng làm tham số đầu tiên cho list.insert[] giả định rằng a đã được sắp xếp

Điểm chèn được trả về i chia mảng a thành hai nửa sao cho all[val = x for val in a[i : hi]] cho bên phải

key chỉ định một trong một đối số được sử dụng để trích xuất khóa so sánh từ mỗi phần tử trong mảng. Để hỗ trợ tìm kiếm các bản ghi phức tạp, hàm key không được áp dụng cho giá trị x

Nếu khóa là None, các phần tử được so sánh trực tiếp mà không cần gọi hàm can thiệp

Đã thay đổi trong phiên bản 3. 10. Đã thêm tham số chính.

chia đôi. bisect_right[a , x , lo=0 , hi=len[a] , * , phím=Không có]chia đôi. chia đôi[a , x , lo=0 , hi=len[a] , * , key=Không có]

Tương tự như , nhưng trả về một điểm chèn xuất hiện sau [ở bên phải] bất kỳ mục nhập hiện có nào của x trong một

Điểm chèn trả về i chia mảng a thành hai nửa sao cho

>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
1 cho bên trái và
>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
2 cho bên phải

key chỉ định một trong một đối số được sử dụng để trích xuất khóa so sánh từ mỗi phần tử trong mảng. Để hỗ trợ tìm kiếm các bản ghi phức tạp, hàm key không được áp dụng cho giá trị x

Nếu khóa là None, các phần tử được so sánh trực tiếp mà không cần gọi hàm can thiệp

Đã thay đổi trong phiên bản 3. 10. Đã thêm tham số chính.

chia đôi. insort_left[a , x , lo=0 , hi=len[a] , * , key=Không có]

Chèn x vào một thứ tự được sắp xếp

Chức năng này chạy đầu tiên để xác định vị trí một điểm chèn. Tiếp theo, nó chạy phương thức

>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
5 trên a để chèn x vào vị trí thích hợp để duy trì thứ tự sắp xếp

Để hỗ trợ chèn bản ghi vào bảng, hàm khóa [nếu có] được áp dụng cho x cho bước tìm kiếm nhưng không áp dụng cho bước chèn

Hãy nhớ rằng tìm kiếm

>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
6 bị chi phối bởi bước chèn chậm O[n]

Đã thay đổi trong phiên bản 3. 10. Đã thêm tham số chính.

chia đôi. insort_right[a , x , lo=0 , hi=len[a] , * , phím=Không có]chia đôi. sắp xếp[a , x , lo=0 , hi=len[a] , * , key=Không có]

Tương tự như , nhưng chèn x vào sau bất kỳ mục nhập hiện có nào của x

Chức năng này chạy đầu tiên để xác định vị trí một điểm chèn. Tiếp theo, nó chạy phương thức

>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
5 trên a để chèn x vào vị trí thích hợp để duy trì thứ tự sắp xếp

Để hỗ trợ chèn bản ghi vào bảng, hàm khóa [nếu có] được áp dụng cho x cho bước tìm kiếm nhưng không áp dụng cho bước chèn

Hãy nhớ rằng tìm kiếm

>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
6 bị chi phối bởi bước chèn chậm O[n]

Đã thay đổi trong phiên bản 3. 10. Đã thêm tham số chính.

Ghi chú hiệu suất

Khi viết mã nhạy cảm với thời gian bằng cách sử dụng bisect[] và insort[], hãy ghi nhớ những suy nghĩ này

  • Chia đôi có hiệu quả để tìm kiếm phạm vi giá trị. Để định vị các giá trị cụ thể, từ điển hiệu quả hơn

  • Các hàm insort[] là

    >>> from collections import namedtuple
    >>> from operator import attrgetter
    >>> from bisect import bisect, insort
    >>> from pprint import pprint
    
    >>> Movie = namedtuple['Movie', ['name', 'released', 'director']]
    
    >>> movies = [
    ..     Movie['Jaws', 1975, 'Speilberg'],
    ..     Movie['Titanic', 1997, 'Cameron'],
    ..     Movie['The Birds', 1963, 'Hitchcock'],
    ..     Movie['Aliens', 1986, 'Scott']
    .. ]
    
    >>> # Find the first movie released after 1960
    >>> by_year = attrgetter['released']
    >>> movies.sort[key=by_year]
    >>> movies[bisect[movies, 1960, key=by_year]]
    Movie[name='The Birds', released=1963, director='Hitchcock']
    
    >>> # Insert a movie while maintaining sort order
    >>> romance = Movie['Love Story', 1970, 'Hiller']
    >>> insort[movies, romance, key=by_year]
    >>> pprint[movies]
    [Movie[name='The Birds', released=1963, director='Hitchcock'],
     Movie[name='Love Story', released=1970, director='Hiller'],
     Movie[name='Jaws', released=1975, director='Speilberg'],
     Movie[name='Aliens', released=1986, director='Scott'],
     Movie[name='Titanic', released=1997, director='Cameron']]
    
    1 vì bước tìm kiếm logarit bị chi phối bởi bước chèn thời gian tuyến tính

  • Các chức năng tìm kiếm là không trạng thái và loại bỏ các kết quả của chức năng chính sau khi chúng được sử dụng. Do đó, nếu các hàm tìm kiếm được sử dụng trong một vòng lặp, thì hàm chính có thể được gọi đi gọi lại trên cùng một phần tử mảng. Nếu chức năng chính không nhanh, hãy xem xét gói chức năng đó để tránh tính toán trùng lặp. Ngoài ra, hãy xem xét việc tìm kiếm một dãy các khóa được tính toán trước để định vị điểm chèn [như minh họa trong phần ví dụ bên dưới]

Xem thêm

  • Bộ sưu tập được sắp xếp là một mô-đun hiệu suất cao sử dụng chia đôi cho các bộ sưu tập dữ liệu được sắp xếp được quản lý

  • Công thức SortedCollection sử dụng bisect để xây dựng một lớp bộ sưu tập đầy đủ tính năng với các phương thức tìm kiếm đơn giản và hỗ trợ cho hàm khóa. Các phím được tính toán trước để lưu các cuộc gọi không cần thiết đến chức năng của phím trong quá trình tìm kiếm

Tìm kiếm danh sách được sắp xếp

Các chức năng trên rất hữu ích để tìm điểm chèn nhưng có thể phức tạp hoặc khó sử dụng cho các tác vụ tìm kiếm thông thường. Năm chức năng sau đây cho thấy cách chuyển đổi chúng thành tra cứu tiêu chuẩn cho danh sách được sắp xếp

________số 8_______

ví dụ

Hàm này có thể hữu ích cho việc tra cứu bảng số. Ví dụ này sử dụng để tra cứu điểm chữ cái cho điểm bài kiểm tra [giả sử] dựa trên một tập hợp các điểm ngắt số theo thứ tự. 90 trở lên là 'A', 80 đến 89 là 'B', v.v.

>>> def grade[score, breakpoints=[60, 70, 80, 90], grades='FDCBA']:
..     i = bisect[breakpoints, score]
..     return grades[i]
...
>>> [grade[score] for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']

Các chức năng và cũng hoạt động với danh sách các bộ dữ liệu. Đối số chính có thể dùng để trích xuất trường được sử dụng để sắp xếp thứ tự các bản ghi trong bảng

>>> from collections import namedtuple
>>> from operator import attrgetter
>>> from bisect import bisect, insort
>>> from pprint import pprint

>>> Movie = namedtuple['Movie', ['name', 'released', 'director']]

>>> movies = [
..     Movie['Jaws', 1975, 'Speilberg'],
..     Movie['Titanic', 1997, 'Cameron'],
..     Movie['The Birds', 1963, 'Hitchcock'],
..     Movie['Aliens', 1986, 'Scott']
.. ]

>>> # Find the first movie released after 1960
>>> by_year = attrgetter['released']
>>> movies.sort[key=by_year]
>>> movies[bisect[movies, 1960, key=by_year]]
Movie[name='The Birds', released=1963, director='Hitchcock']

>>> # Insert a movie while maintaining sort order
>>> romance = Movie['Love Story', 1970, 'Hiller']
>>> insort[movies, romance, key=by_year]
>>> pprint[movies]
[Movie[name='The Birds', released=1963, director='Hitchcock'],
 Movie[name='Love Story', released=1970, director='Hiller'],
 Movie[name='Jaws', released=1975, director='Speilberg'],
 Movie[name='Aliens', released=1986, director='Scott'],
 Movie[name='Titanic', released=1997, director='Cameron']]

Nếu chức năng khóa đắt tiền, có thể tránh các cuộc gọi chức năng lặp lại bằng cách tìm kiếm danh sách các khóa được tính toán trước để tìm chỉ mục của bản ghi

sắp xếp nhị phân là gì?

Sắp xếp chèn nhị phân là một thuật toán sắp xếp tương tự như sắp xếp chèn, nhưng thay vì sử dụng tìm kiếm tuyến tính để tìm vị trí mà một phần tử sẽ được chèn vào, chúng tôi sử dụng tìm kiếm nhị phân . Do đó, chúng tôi giảm giá trị so sánh của việc chèn một phần tử từ O [N] xuống O [log N]. . Thus, we reduce the comparative value of inserting a single element from O [N] to O [log N].

Python có phương pháp tìm kiếm nhị phân không?

Tìm kiếm nhị phân trong python là một kỹ thuật tìm kiếm hoạt động trên một mảng được sắp xếp . Thay vì so sánh từng phần tử của mảng với phần tử được yêu cầu, thuật toán tìm kiếm nhị phân liên tục chia mảng thành các mảng con rồi tìm kiếm phần tử được yêu cầu trong mảng con.

Là sắp xếp nhị phân nhanh nhất?

Như bạn có thể thấy, sắp xếp chèn nhị phân là thuật toán nhanh nhất trong ba thuật toán cho đến khoảng n = 55 . Tại thời điểm đó, sắp xếp hợp nhất trở nên nhanh hơn và nó vẫn nhanh hơn đối với tất cả các đầu vào lớn hơn.

Sắp xếp nhanh có giống với sắp xếp nhị phân không?

Quicksort là một trong những thuật toán sắp xếp [nhanh] nhanh nhất và được sử dụng nhiều nhất trong các tập dữ liệu khổng lồ. Nó hoạt động thực sự tốt trong những tình huống như vậy. Cây tìm kiếm nhị phân là một trong những thuật toán tìm kiếm nhanh nhất và được áp dụng trong tập dữ liệu đã được sắp xếp. Nó giảm không gian tìm kiếm xuống 2 trong mỗi lần lặp lại, do đó tên của nó [nhị phân].

Chủ Đề