IT 취미생활.  
Front Page
Tag | Location | Media | Guestbook | Admin   
 
'Programming/알고리즘'에 해당하는 글(5)
2008.10.18   [알고리즘] Insertion Sort(삽입정렬)
2008.10.17   [알고리즘] Priority Queue (우선 순위큐)
2008.10.17   [알고리즘] Selection Sort
2008.10.16   [알고리즘] BubbleSort
2008.07.21   [알고리즘]힙(heap)을 이용한 우선순위 큐 1


[알고리즘] Insertion Sort(삽입정렬)
간단하게 작성한 삽입 정렬입니다.


간단하게 원리를 설명드리면, 배열에 index는 1에서 부터 시작해서(1 <= x < N ) N까지
정렬을 합니다.  index한 녀석을 집어 넣을 위치를 찾는 것입니다.

코드는 따로 설명 드리지 않겠습니다.

void InsertSort( int *_arrayBuffer, int _bufferSize )
{
  for( int i = 1; i < _bufferSize; i++ )
  {
    int insertionValue= _arrayBuffer[ i ];
    int nInsertPosition = i;
    while( _arrayBuffer[nInsertPosition-1] > insertionValue && nInsertPosition > 0 )
    {
      _arrayBuffer[nInsertPosition ] = _arrayBuffer[ nInsertPosition - 1 ];
      nInsertPosition--;
    }
    _arrayBuffer[ nInsertPosition ] = insertionValue;
  }
}

배열안에 값들이 정렬이 이루어져 있으면 N 에 대한 성능을 가질 수 있다고 하는군요.

그럼 고운하루 되세요.



[알고리즘] Priority Queue (우선 순위큐)

Project에 적용하기 위해서 작성한 Heap을 기반으로한 Priority Queue Class 입니다.
MultiThread-Safe 하긴한데 performance가 따라 줄지는 모르겟습니다.
성능 개선을 위한 부분 있다면 언제든지 코멘트 부탁 드립니다 ㅜㅜ;;;;

딱 보면 아시겠지만, 생각하는 프로그래머에 Code를 그대로 옮겨 놓은 듯 합니다.
^0^ 그럼 고운하루 되세요.

template< class T >
class CPriQueue
{
private:
 int m_nCurIndex, m_nMaxsize;
 CRITICAL_SECTION m_cs;
 T *m_pTemplateArray;

 void swap( int i, int j )
 {  
  T t = m_pTemplateArray[i];
  m_pTemplateArray[i] = m_pTemplateArray[j];
  m_pTemplateArray[j] = t;
 }

public:
 CPriQueue()
 {
  m_pTemplateArray = NULL;
  InitializeCriticalSection( &m_cs );
 }

 ~CPriQueue()
 {
  FlushQueue();
  delete []m_pTemplateArray;
  DeleteCriticalSection( &m_cs );
  m_pTemplateArray = NULL;
 }

 void SetQueueSize( unsigned int QueueSize )
 {
  if( QueueSize <= 0 )
   QueueSize = 1;

  m_pTemplateArray = new T[ QueueSize +1 ];
  if( m_pTemplateArray )
  {
   m_nMaxsize = QueueSize;
   m_nCurIndex = 0;
  }
 }

 void Push( T t )
 {
  if( m_nCurIndex >= m_nMaxsize   )
  {
   FlushQueue();
   printf("******FULL Queue ******* ");
   return;
  }

  int nParentIndex;
  EnterCriticalSection( &m_cs );
  m_pTemplateArray[ ++m_nCurIndex ] = t;


  if(  m_nCurIndex >  1 && m_pTemplateArray[ nParentIndex = m_nCurIndex >> 1  ] > m_pTemplateArray[m_nCurIndex] )
  { 
   for ( int nCurrentIndex = m_nCurIndex;
    nCurrentIndex > 1 && m_pTemplateArray[ nParentIndex = nCurrentIndex >> 1  ] > m_pTemplateArray[nCurrentIndex];
    nCurrentIndex = nParentIndex )
   {
    swap( nParentIndex, nCurrentIndex );
   }
  }
  LeaveCriticalSection( &m_cs );
 }


 T Pop()
 {
  if ( m_nCurIndex == 0 )
  {
   return 0;
  }

  int nChild = 0;
  EnterCriticalSection( &m_cs );
  T  t = m_pTemplateArray[ 1 ];
  m_pTemplateArray[ 1 ] = m_pTemplateArray[ m_nCurIndex-- ];

  for(  int i = 1; ( nChild =  i << 1 ) <= m_nCurIndex ; i = nChild )
  {
   if( nChild + 1 <= m_nCurIndex && m_pTemplateArray[ nChild + 1 ] < m_pTemplateArray[ nChild ] )
   {
    nChild++;
   }

   if( m_pTemplateArray[ i ] <= m_pTemplateArray[ nChild ]  )
   {
    break;
   }
   swap( nChild, i );
  }
  LeaveCriticalSection( &m_cs);
  return t;
 }
 
 void FlushQueue()
 {
  UINT nfreameCount = 0;
  T tFrame  = NULL;
  while( tFrame = Pop() )
  {
   delete tFrame;
   tFrame  = NULL;
   nfreameCount++;
  }
  m_nCurIndex = 0;
  printf("******Flush Queue *******  :: %d \n", nfreameCount );
 }
};



[알고리즘] Selection Sort

프로그래밍 불여일타!!의 프로젝트의 일환으로, 퇴근후 배깔고 하는 알고리즘 공부를 시작!!
그 결과물로 간단 간단한 알고리즘을 작성하고, Blog에 올리기로 했습니다.

오늘은 간단하게 Selection Sort를 만들어 보았습니다.

* 원리는 : 총 1...n개의 정렬 되지 않은 요소에서, 첫번째 놈을 가져다가 가장 작은 값을
              가진다라 가정 하고  나머지 n-1개와 비교를 하게 합니다. 그래서 그중 가장
              작은 녀석을 기억 하고 있다가, 1번째 자리와 바꿉니다. 그리고 index을 하나 더
              증가 해서 두번째 요소를 가지고  n-2 만큼 loop를 돌아서 다시 최소값을 찾고
              바꿔 줍니다. 이렇게 반복하면 정렬이 됩니다.( 사실 그림으로 보면 아무것도
              아닙니다. 그림은 귀찮아서 안그렸습니다.)

* 성능 :  O(N^2)

* 코드

void swap( int *a, int *b )
{
     int dump = *a;
     *a = *b;
     *b = dump;
}

void SelectionSort( int *_arrayBuffer, const unsigned int _arraySize )
{
     for( int i = 0; i < _arraySize; i++ )
     {
          int nMinIndex = i;
          for( int j = i + 1; j < _arraySize; j++ )
          {
               if( _arrayBuffer[j] < _arrayBuffer[nMinIndex] )
               {
                   nMinIndex = j;
               }
          }
          swap( _arrayBuffer[nMinIndex], _arrayBuffer[ i ] );
      }  
}


[알고리즘] BubbleSort

간단하게 Bubble Sort을 만들어 보았습니다.

정렬 방식은 Buffer 마지막에 가장 큰 값을 옮겨두고, 첫 번째 for loop의 index를 -- 하여
뒤에서 부터 큰 값들이 정렬되도록 하는 sorting 방법입니다.
알고리즘 효율은 O(N^2) 입니다.

Function 이름은 "한눈에 보이는 C 알고리즘"이라는 책에서 가져다 사용 했습니다. - 귀차니즘

프로그래밍의 왕도는 역시 불여일타!!!!





#include <cstdlib>
#include <iostream>

using namespace std;


#define MAX_SIZE 100

int NumberExit( int *_arrayBuffer, int _number, int _index)
{
    for( int i=1 ; i < _index; i++ )
    {
            if( _arrayBuffer[i] == _number )
            {
                return true;
            }
    }
    return false;
}

void MakeRendomNumber( int *_arrayBuffer )
{
     int nNum = 0;
     srand( (unsigned)time( NULL ) );
     _arrayBuffer[0] = MAX_SIZE;
     int i = 1;
     while( i < MAX_SIZE )
     {
            nNum = rand() % MAX_SIZE;
            if( false == NumberExit( _arrayBuffer, nNum, i ))
            {
                _arrayBuffer[i] = nNum;
                i++;
            }
     }
}

void DisplayBuffer( int *_arrayBuffer )
{
     for( int i = 0; i < MAX_SIZE; i ++ )
     {
          if( (i % 10) == 0 )
          {
              cout << "\n";
          }
          cout << _arrayBuffer[i] << "\t";
     }
     cout << "\n";
}


 

void BubbleSort( int *_arrayBuffer, const unsigned int _arraySize )
{
     for( int i = _arraySize - 1; i >= 0; i-- )
     {
          for( int j = 1; j <= i ; j++ )
          {
               if( _arrayBuffer[ j - 1 ] > _arrayBuffer[ j ] )
               {
                   int nDummy  = _arrayBuffer[ j - 1 ];
                   _arrayBuffer[ j - 1 ] = _arrayBuffer[ j ];
                   _arrayBuffer[ j ] = nDummy;
               }
          }
     }
}

int main(int argc, char *argv[])
{
    int Buffer[ MAX_SIZE ] = { 0 };
   
    MakeRendomNumber( Buffer );
    DisplayBuffer( Buffer );
    cout << "\n";
   
    BubbleSort( Buffer, MAX_SIZE );
    cout << "\n";
    DisplayBuffer( Buffer );
   
    system("PAUSE");
       
    return EXIT_SUCCESS;
}



[알고리즘]힙(heap)을 이용한 우선순위 큐

대딩때 가장 즐겁게 만들었던  우선순위 Heap입니다.^^
참 단촐 하면서도 가장 재미있게 한 레포트였습니다.

항상 n-1을 유지 하기 때문에 Static 한 Arrary를 Pointer 이용하여 각 노드들의
포인터만 저장 될 수 있도록 하고 Indexing을 통하여 우선순위 Heap을 핸들링 하는 것이
좋겠다 생각 한다.

Push와 Pop을 이용하여 새로운 Node를 삽입하게 되고
삽입 된 노드는 항상 가장 아래에 입력이 됩니다. 즉 N-1에 입력이 된다고 할 수 있다.

Pop이 이루어질 때는 우선 순위가 갖아 높은 최상의 Node가 Pop이 되고
Pop이 되면 자식 노드중 가장 큰 값을 다시 최상으로 올리는 재배열이
이루어져야 한다.

요것만 지켜지면 Max Heap이 됩니다.


 

아래 내용은 내용의 출처는 http://timenote.net/ 에  기록자 님의 작성한 원문이다.
특별히 저자분의 동의 없이 내용을 훔쳐 왔다는게 마음에 걸리고 동의를 받아야 하겠다.

힙(heap)이란 특수한 형태의 완전이진트리의 구조를 가진다.
힙은 각 노드의 키 값이(자식이 있다면) 그 자식의 키 값보다 작지 않은 완전 이진 트리이다.
힙의 구조를 살펴보면 아래와 같다.

사용자 삽입 이미지

완전 이진트리인 힙의 일반적인 형태


힙은 일반적으로 우선순위 큐(priority queue)를 구현할 때 자주 사용된다.
이전에 구현해 보았던 큐와는 달리 우선순위 큐에서는 우선순위가 가장 높은 원소를 먼저 삭제한다.
예를 들어 운영체제의 작업 스케줄러가 관리자에게 높은 우선순위를 부여하고 학생에게는 낮은 우선순위를 부여하는 우선순위 시스템을 사용한다고 가정하자.
이 경우 작업들을 유지하는 우선순위 큐를 최대 힙으로 구현할 수 있다.

힙은 우선순위 큐를 구현하는 한 방법일 뿐이다.
실제로 우선순위큐를 표현하기 위한 방법으로는 순서없는 배열, 순서없는 연결 리스트, 정렬된 배열, 정렬된 연결 리스트, 힙 등이 있다.
이 중 삽입과 삭제에 대한 복잡도가 둘다 log n의 복잡도를 가지는 것은 힙이다.
그렇기 때문에 우선순위큐를 표현하는 방법들중 힙을 선호하게 만든다.
그러면 힙의 삽입과 삭제 방법을 보도록하자.

아래 그림은 힙의 삽입 방법이다.

사용자 삽입 이미지

힙에서의 삽입 과정은 배열의 제일 뒤에 새로운 원소를 삽입하고 부모 노드의 키 값과 비교해서 부모 노드보다 작을 때까지 교체과정을 거친다.
즉, 삽입시에 최대한의 비교과정을 거치더라도 루트 노드까지만 비교하면 되므로 복잡도는 log n 을 따르게 된다.
다음은 힙에서 삭제가 일어나는 과정을 보도록 하겠다.

사용자 삽입 이미지

힙에서의 삭제 과정


힙에서의 삭제는 항상 루트의 값이 제거 되므로 루트의 값이 제거된 후에도 힙을 유지할 수 있도록 하기 위한 처리가 필요하다.
우선 완전 이진트리가 되어야 하므로 제일 뒤의 원소(여기서는 6)를 루트의 자리에 위치 시킨다.
그리고 힙의 특성상(여기서는 최대힙) 부모노드의 키값이 자식 노드의 키값보다 커야 하므로 자식 노드와 비교하면서 키값이 자식노드보다 클 때까지 반복해 나간다.

아래에는 힙을 구현하여 소스코드를 작성해 보았다.


그럼 고운하루... 되세요.
 



BLOG main image
취미생활
 Notice
 Category
분류 전체보기 (191)
매일매일갱생 (83)
서버개발 (1)
임베디드개발 (12)
Programming (80)
개발잡념 (10)
C (6)
C++ (5)
Java (4)
알고리즘 (5)
VC++ (11)
DirectShow (5)
OS (1)
Error Case (13)
Personal Projects (6)
유용한 프로그램 (0)
 TAGS
project 영어 이메일 C++ ISDB-T 미라지폰 M480 DVB DVB-T isdbt 벨소리 변경 VC++ Dshow Java It 퇴사 spam mail Error Case Linux MP3 출장 군대 Windows Mobile6.0 티스토리초대 C Algorithm 개발자 warning 음식 1seg 서태지 DirectShow Brazil 알고리즘 티스토리 초대장 english email Debug English debugging Wince5.0
 Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
 Recent Entries
 Recent Comments
 Recent Trackbacks
 Archive
 Link Site
zextor
괴짜 프로그래머의 일상사~@@
Gag & Peace, and more..
Kazakhstan Almaty.......
Min-A
Sadgarret
Steve Yoon's log
가슴 뛰는 삶을 살아라
오스틴 파워
GUI sin
melanie parker_Lady
제레미의 TV 2.0 이야기..
 Visitor Statistics
Total :
Today :
Yesterday :
rss