[イコタ]配列


ソートとは?
=>データを特定の条件順にリスト

  • プログラムでデータを加工する場合、昇順や降順など多様な方法で並べ替えて使用されることが多く、並べ替えアルゴリズムはプログラムを作成する際によく使われるアルゴリズムの一つである.

  • ソートアルゴリズムを使用してデータをソートする場合は、次の章でバイナリ検索を学習できます.

  • すべての昇順ソートを実行します.降順ソートでは、昇順ソートを実行するアルゴリズムでサイズ比較を逆方向に実行できます.=>また、Pythonは、特定のリストの要素を反転させる方法も提供しています.
  • ソートの選択
    =>データがランダムである場合、最小のデータを先頭のデータに置き換え、小さいデータを選択して前の2番目のデータ置換プロセスを繰り返すとどうなりますか?
  • は、「最小選択」を表すたびに、「選択」ソートアルゴリズムと呼ばれる.
  • array = [7,5,9,0,3,1,6,2,4,8]
    

    for i in range(len(array)):

    min_index = i # 가장 작은 원소의 인덱스
    for j in range(i+1 , len(array)):
    if array[min_index] > array[j]:
    min_index = j

    array[i], array[min_index] = array[min_index], array[i] #스와프
    print(array)

    *시간 복잡도 : O(N제곱)

    • 선택 정렬은 기본 정렬 라이브러리나 뒤에서 다룰 알고리즘에 비해서 매우 비효율적. 그러나 특정한 리스트에서 가장 작은 데이터를 찾는 일이 코딩 테스트에서 잦으므로 형태는 알아두어야 함.

    삽입 정렬(insertion sort)

    데이터를 하나씩 확인하며, 각 데이터를 적절한 위치에 삽입하면 어떨까?!

    • 삽입 정렬은 선택 정렬에 비해 실행 시간 측면에서 더 효율적인 알고리즘

    • 필요할 때만 위치를 바꾸므로 '데이터가 거의 정렬 되어 있을 때' 훨씬 효율적

    • 선택 정렬은 현재 데이터의 상태와 상관없이 무조건 모든 원소를 비교하고 바꾸는 반면 삽입 정렬은 그렇지 않다.

    • 삽입 정렬은 특정한 데이터를 적절한 위치에 "삽입" 한다는 의미에서 "삽입 정렬"

    • 특정한 데이터가 적절한 위치에 들어가기 이전에, 그 앞까지의 데이터는 이미 정렬되어 있다고 가정한다.

    • 정렬되어 있는 데이터 리스트에서 적절한 위치를 찾은 뒤에, 그 위치에 삽입된다는 점이 특징

    • 삽입 정렬은 두번째 데이터 부터 시작한다. 왜냐하면 첫 번째 데이터는 그 자체로 정렬되어 있다고 판단하기 때문이다.

    • 삽입 정렬의 특징으로는 정렬이 이루어진 원소는 항상 오름차순을 유지하고 있다는 점이다.

    -> 이러한 특징 때문에 삽입 정렬에서는 특정한 데이터가 삽입될 위치를 선정할 때(삽입할 위치를 찾기 위하여 한 칸씩 이동할 때),삽입될 데이터보다 작은 데이터를 만나면 그 위치에서 멈추면 된다.

    #삽입 정렬
    
    array = [7,5,9,0,3,1,6,2,4,8]
    
    for i in range(1, len(array)) :
      for j in range(i, 0, -1): # 인덱스 i부터 1까지 감소하며 반복하는 문법
        if array[j] < array[j -1]:  #한 칸씩 왼쪽으로 이동
            array[j], array[j -1] = array[j -1], array[j]
        else: #  자기보다 작은 데이터를 만나면 그 위치에서 멈춤
          break
    print(array)
    cf)範囲内の三次曲面パラメータ
    rangeのパラメータは3つ(srart,end,step)ある.3番目のパラメータに-1を加えるとstartインデックスからend+1インデックスまで1ずつ減算されます.
    *時間複雑度:O(N二乗)
  • 現在のリストのデータがほぼソート状態にある場合、動作は非常に速い
  • である.
    クイックソート
    データムデータを設定し、ビッグデータとビッグデータの位置を変更したらどうですか?

  • クイックソートは、標準を設定し、大数と小数を交換し、リストを半分にする方法です.

  • クイックソートにはピボット(pivot)が使用されます.ピボットは、大きな数字と小さい数字を交換するときに、交換する「標準」がピボットであることを示します.

  • クイックソートを実行する前に、ピボットを設定する方法を事前に説明する必要があります.クイックソートは、最も代表的な分割方法である円弧分割(Hoare Partition)に基づいて説明します.

  • 円弧分割方法では、リスト内の最初のデータをピボットとします.

  • 「≪クイック・ソート|Quick Sort|Essbase_Studio≫」で、特定のリストにピボットを設定してソートし、ピボットに基づいて左側のリストと右側のリストでそれぞれ並べ替えます.
    =>再帰関数と動作原理は同じ

  • 再帰関数と動作原理が同じであれば,終了条件もあるはずである.
    =>現在のリストに1つのデータがある場合
    =>リストに要素がある場合は、ソートされたものとみなされ、分割できません.
  • #퀵 정렬
    
    array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
    
    
    def quick_sort(array, start, end) :
      if start >= end: #원소가 1개인 경우 종료
        return
      pivot = start
      left = start + 1
      right = end
      while left <= right:
        #피벗보다 큰 데이터를 찾을 때까지 반복
        while left <= end and array[left] <= array[pivot]:
          left += 1
    
        #피벗보다 작은 데이터를 찾을 때까지 반복
        while right > start and array[right] >= array[pivot]:
          right -= 1
    
        if left > right: #엇갈렸다면 작은 데이터와 피벗을 교체
          array[right], array[pivot] = array[pivot], array[right]
        
        else: # 엇갈리지 않았다면 작은 데이터와 피벗을 교체
          array[left], array[right] = array[right], array[left]
    
        #분할 이후 왼쪽과 오른쪽 부분에서 각각 정렬 수행
    
      quick_sort(array, start, right - 1)
      quick_sort(array, right +1, end)
    
    
    
    quick_sort(array, 0, len(array)-1)
    print(array)</code></pre>
    
    #퀵 소트,시간 면에서는 비효율
    
    array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8]
    
    
    def quick_sort(array):
      # 리스트가 하나 이하의 원소만을 담고 있다면 종료
      if len(array) &lt;= 1:
        return array
    
      pivot = array[0] #피벗은 첫 번째 원소
      tail = array[1:] # 피벗을 제외한 리스트 
    
    
      left_side = [x for x in tail if x &lt;= pivot] #분할된 왼쪽 부분
      right_side = [x for x in tail if x &gt;= pivot] #분할된 오른쪽 부분
    
    
    
    
      #분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬을 수행하고, 전체 리스트를 반환 
      return quick_sort(left_side) + [pivot] + quick_sort(right_side)
    
    print(quick_sort(array))
    

  • 高速ソートの時間的複雑度:平均時間的複雑度はO(Nlogn)である.挿入や選択よりも速いです.
    =>軸値の位置が変化しているため、分割が発生するたびに左側リストと右側リストを正しく半分に分割すると、データの個数がnの場合、高さはlognとなる.(書画参照)
    すなわち,分割回数は幾何級数的に減少する.

  • 一般的に、コンピュータ科学では、ログの意味は2つの下部のログです.

  • 平均はO(Nlogn)であるが,最悪の場合時間的複雑度はO(n平方)である.
    =>データがランダムに入力されている場合、高速ソートの速度は非常に速くなりますが、上記のように円弧で分割してリストの一番左のデータを軸にすると、「データがソートされている場合」の速度は非常に遅くなります.
  • カウントソート

  • 特定の条件を満たす場合にのみ使用できる非常に高速なソートアルゴリズムです.

  • 一般的に、ソートに関する情報を含む個別のリストを宣言するのが特徴です.

  • 「データのサイズ範囲が限られており、整数で表すことができる場合」にのみ使用できます.

  • したがって,与えられたデータの値が無限範囲の実数型データを有する場合,係数ソートを用いることは困難である.

  • 通常、最大と最小のデータの差が1000000を超えない場合、それらを有効に使用することができる.
    ->係数ソートがこれらの特徴を持つのは、係数ソートを使用する場合、**がすべての範囲を含むリスト(配列)**を宣言する必要があるためです.

  • カウントソートは、前述した3つのソートアルゴリズムと同様に、データ値を直接比較し、位置を変更してソートする方法(比較に基づくソートアルゴリズム)ではありません.
  • array = [7,5,9,0,3,1,6,2,9,1,4,8,0,5,2]
    
    #모든 범위를 포함하는 리스트 선언(모든 값은 0으로 초기화)
    
    print(max(array))
    
    count = [0] * (max(array) + 1)
    
    
    for i in range(len(array)) :
      count[array[i]] += 1 # 각 데이터에 해당하는 인덱스의 값 증가
    
    
    for i in range(len(count)): # 리스트에 기록된 정렬 정보 확인
      for j in range(count[i]):
        print(i, end =' ') # 띄어쓰기를 구분으로 등장한 횟수만큼 인덱스 출력
  • 係数ソートの時間的複雑さ
    =>データの個数がNであり、データ内の最大値の大きさがkである場合、カウントソートの時間的複雑度はO(N+K)である.カウント・ソートは、前からデータを1つずつチェックするため、リストに対応するインデックスの値1を追加し、その後、リスト内の各インデックスに対応する値をチェックする場合、データの最長値のサイズを繰り返し実行する必要があります.
    =>実際,既存のソートアルゴリズムでは,基数ソート(Radix Sort)とともに最も速いと考えられる.
  • 係数ソートの空間的複雑さ
    =>ソート・カウントは、重大な非効率をもたらす場合があります.ex)0と9999999999セグメントの2つのデータしかないと仮定します.この場合、リストの大きさも100万個に達し、マークを発表します.
    =>したがって、これは一般的なアルゴリズムではなく、同じ値を持つ複数のデータが表示される場合に理想的な選択です.
  • Pythonのソートライブラリ
  • Pythonは、基本ソートライブラリソート()関数を提供します.
  • <ソート()関数>
    -クイックソート動作に似たマージソートに基づいています.
    -連結ソートは通常、高速ソートよりも遅いが、最悪の場合でも時間的複雑度O(Nlogn)を保証することができる.
    -リスト、ディクシャナリーデータ型を入力し、ソート結果をリストデータ型に出力します.
    array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8]
    
    result_1 = sorted(array #sorted 함수
    
    array.sort() # sort함수 별도의 정렬된 리스트가 반환되지 않고, 내부 원소가 바로 정렬
    
    print(result_1)
    print("------------")
    print(array)
    
    
    array_1 = [("바나나", 2), ("사과", 5), ("당근", 3)]
    
    def setting(data):
      return data[1]
    
    result = sorted(array_1, key = setting)
    print(result)
    

  • sorded()またはsort()を使用する場合はkeyパラメータを入力できます.key値には、ソート基準である関数が含まれている必要があります.

  • ソート・ライブラリの時間的複雑さ
    −最悪の場合でも時間的複雑度O(NlonN)を保証する.
    -作成された関数
    -問題に他の要件がない場合は、単純なソートが必要な場合はデフォルトのソート・ライブラリを使用します.データ範囲が限られており、より迅速な操作が必要な場合は、カウント・ソートを使用します.
  • #N을 입력받기
    
    n = int(input())
    
    #N개의 정수를 입력받아 리스트에 저장
    
    array = []
    for i in range(n):
      array.append(int(input()))
    
    array = sorted(array, reverse = True)
    
    for i in array:
      print(i, end = " ")</code></pre>
    <h2 id="성적이-낮은-순서로-학생-출력하기">성적이 낮은 순서로 학생 출력하기</h2>
    <pre class=" language-null"><code class=" language-null">#N을 입력받기
    n = int(input())
    
    
    #N명의 학생 정보를 입력받아 리스트에 자장
    array = []
    for i in range(n):
      input_data = input().split()
      #이름은 문자열 그대로, 점수는 정수형으로 변환하여 저장
      array.append((input_data[0], int(input_data[1])))
    
    
    #키(key)를 용하여, 점수를 기준으로 정렬
    array = sorted(array, key = lambda student: student[1])
    
    #정렬이 수행된 결과를 출력
    for student in array:
      print(student[0], end = '')
    2つの配列の要素を置換
    n, k = map(int, input().split())
    
    # N과 K를 입력받기
    a = list(map(int, input().split())) #배열 A의 모든  원소를 입력받기
    b = list(map(int, input().split())) #배열 B의 모든 원소를 입력받기
    
    a.sort() #배열 A는 오름차순 정렬 수행
    b.sort(reverse = True) #배열 B는 내림차순 정렬 수행
    
    
    for i in range(k):
      #A의 원소가 B의 원소보다 작은 경우
      if a[i] &lt; b[i]:
        # 두 원소를 교체
        a[i], b[i] = b[i], a[i]
      else: # A의 원소가 B의 원소보다 크거나 같을 때, 반복문을 탈출
        break   
    
    
    
    print(sum(a)) #배열 A의 모든 원소의 합을 출력