U E D R , A S I H C RSS

Data Structure/List



1. 리스트


  • 리스트란 무엇인 하니... 저장하 싶은 데이터와 다음 데이터를 가르키는 포인터를 구조체로 묶은 노드를 기본으로 해서 막~ 연결시켜준 것이다.

~cpp 
struct Node    // 제가 c문법을 잘 모릅니다.. 책에서는 typedef인가? 이상한걸 쓰더군요.
{
    int lalala;    // 넣 싶은 데이터
    Node* Next_ptr;   // 다음 데이터를 가르키는 포인터
};

c 문법으로 하면.
~cpp 
typedef struct {
	int data;
	Node * link;
} Node;

  • 리스트를 사용하는 간단한 예

~cpp 
...
Node* kkk=new Node;   // 동적 생성
kkk->lalala=100;      // kkk의 멤버 lalala에 100을 넣음.
Node* hhh=new Node;   // 새롭게 동적 생성
kkk->Next_ptr=hhh;    // kkk의 멤버 Next_ptr이 다음 노드인 hhh를 가르키게 함
hhh->lalala=50;       // hhh에 데이터 넣음
hhh->Next_ptr=NULL;   // hhh뒤에 아무것도 없으니 다음 노드를 가르키는 포인터를 NULL로 설정함
...
...
delete kkk;           // new로 한건 꼭 delete로 지워주자
delete hhh;

  • 위와 같이 다음 또는 먼저번 노드를 가르키는 포인터가 하나만 있는 것을 Single Linked List라 한다.
  • 반면에 둘 다 있는 것을 Double Linked List라 한다.
  • Single Linked List에서는 한 쪽으로만 이동이 가능하기 때문에 멀리 있는 노드를 찾아가는데에 시간이 좀 오래걸린다.
  • 이를 보완하기 위해 나온 것이 Double Linked List이다.
  • Double Linked List에서는 맨 마지막 노드의 다음 노드가 NULL이 아닌 맨 처음 노드를 가르킨다.
  • 마찬가지로 맨 처음 노드의 앞 노드는 맨 마지막 노드가 된다.
  • 결론적으로 Single은 체인모양 Double은 리모양이 된다.

  • Double Linked List를 사용한 간단한 예(3개의 노드를 예로 듬)

~cpp 
struct Node
{
    int lalala;
    Node* Next_ptr;
    Node* Prev_ptr;
};

...

Node* Head=new Node; // 1 노드 동적 생성
Node* Mid=new Node;  // 2 노드 동적 생성
Node* Tail=new Node; // 3 노드 동적 생성
Head->Next_ptr=Mid;  // 1 노드의 다음 노드는 2노드
Mid->Next_ptr=Tail;  // 2 노드의 다음 노드는 3노드
Tail->Next_ptr=Head; // 3 노드의 다음 노드는 1노드
Head->Prev_ptr=Tail; // 1 노드의 앞 노드는 3노드
Mid->Prev_ptr=Head;  // 2 노드의 앞 노드는 1노드
Tail->Prev_ptr=Mid;  // 3 노드의 앞 노드는 2노드

...

  • 장점 : 빠르다. (배열 같은 경우는 중간에 하나 지우 나면 그 뒤에껄 다 앞으로 땡겨야 한다. 수행시간 절라 오래 걸린다. 하지만 리스트는 다음 노드를 가리키는 포인터만 바꿔주면 된다.)
  • 단점 : 잘못된 포인터에 의한 Memory Leak 이 발생할 수 있다.

2. 자바로 짠 링크드 리스트(c++로 짜다가 갑자기 비졀씨가 뻗어서 다 날라갔음..--; 혈압올라서 숙제로 내려던 자바 링크드 리스트를 적겠음

~cpp 
import java.io.*;

class Node
{
	private int ndata;
	public Node pNext=null;
	
	public Node(int ndata)
	{
		this.ndata=ndata;
	}

	public int getData()
	{
		return ndata;
	}
}

class MyLinkedList
{
	private Node pHead;
	private Node pTail=null;
	private static int nNumber=0;

	public MyLinkedList()
	{
		pHead=new Node(0);
	}
	
	public void insertNode(int ndata,int nSequence)
	{
		Node pNew=new Node(ndata);

		if(nNumber==0)
			pHead.pNext=pNew;

		Node pTemp=new Node(0);
		pTemp=pHead;
		for(int i=0;i<nSequence;i++)
			pTemp=pTemp.pNext;

		pNew.pNext=pTemp.pNext;		
		pTemp.pNext=pNew;
			
		nNumber++;
	}

	public boolean deleteNode(int nSequence)
	{
		if(nNumber<nSequence)
		{
			System.out.println("저장된 데이터양을 초과하는 인덱스입니다!");
			return false;
		}

		Node pTemp=new Node(0);
		Node pTemp2=new Node(0);
		pTemp=pHead;

		for(int i=0;i<nSequence-1;i++)
			pTemp=pTemp.pNext;

		pTemp2=pTemp.pNext;
		pTemp.pNext=pTemp2.pNext;
	
		nNumber--;
	
		return true;
	}

	public void showData()
	{
		Node pTemp=new Node(0);
		pTemp=pHead;
		int data;

		if(nNumber==0)
			System.out.println("저장된 데이터가 없습니다!");
		
		for(int i=0;i<nNumber;i++)
		{
			pTemp=pTemp.pNext;
			data=pTemp.getData();
			System.out.println(data);
		}
	}

	public void showMenu()
	{
		System.out.println("1. Add");
		System.out.println("2. Delete");
		System.out.println("3. Show");	
		System.out.println("4. End");
		System.out.print("Select the Menu : ");
	}

	public static void main(String args[])
	{
		MyLinkedList ll=new MyLinkedList();
                  /// 이부분에 메뉴를 넣든 함수 호출을 하든 마음대로..
	}
}
  • 뭔가 굉장히 이상하군요..; 제가 봐도..;; 굉장히 조잡하 굉장히 허접한.. 그런 이상한 코드 같습니다.; 자바는 첨이라서 그런가..;
  • LinkedList가 종단 부분에서만 추가,삭제가 되는게 아닌 아무데서나 되야 하더군여. 그래서 그걸 어떻게 정해줄까 민하다가 데이터의 순서로 하기로 했습니다.

= 자바로 짠 링크드 리스트..2 (누가 한걸까) 상협인가?=
~cpp 

소드 다 적으면 아무도 안볼거 같아서.. 

인터페이스와 개략적인 알리즘만 적겠습니다.

제가 자바로 링크드 리스트 짤때 제일 민한 점이 노드를 추가할때마다

전체 노드의 크기가 바뀌는 점을 민 많이 했습니다.

그래서 한것이 노드를 추가할때마다 전체 노드를 다시 만드는 것이었습니다.

(자바의 Vector 클래스에서 이렇게 했다 얼핏 듣어서...)
===> 그 작업이 아래에 있습니다.
    boolean Add_ToSpecial(int coordi, int in) //특정한 위치에 자료를 저장하는 메소드
    {
       if(coordi <0 || coordi >= m_Node.length)  //좌표는 0부터 시작됨, 입력 위치가 해당 범위를 벋어날 경우
            return false;
       Node tempNode[] = new Node[m_Node.length+1]; //m_Node에 하나의 자료를 더 넣기 위해서 이보다 
                                                         //하나의 공간이 더 많은 임시 배열을 생성한다.
        for(int i=0;i<tempNode.length-1 && i<coordi;i++)  //tempNode에 m_Node를 우선 coordi번째(0부터 시작해서) 전의 자리
            tempNode[i] = m_Node[i];   //까지 복사 한다.
       Node tem = new Node();  //임시 노드 생성
       tem.item = in;
       tem.next =  m_Node[coordi];  //낀 곳에 원래 있었던 자료를 참조한다. 
       tempNode[coordi] = tem;
       tempNode[coordi-1].next = tempNode[coordi];  //낀 곳의 바로 앞에 있는 자료가 첨가한 자료를 참조하게 한다.
       for(int j = coordi+1; j<tempNode.length-1;j++)
              tempNode[j] = m_Node[j-1];
        m_Node = new Node[tempNode.length];  // m_Node의 크기를 늘린후 tempNode를 넣는다.
        for(int i=0;i<tempNode.length;i++)  // m_Node 에 tempNode를 복사한다.
             m_Node[i] = tempNode[i];
        return true;                 
    }
//////////////////////////

//노드 클래스 모습과 인터페이스
class Node {            //Node 클래스
    public int item;
    public Node next;
}
void Add_ToFront(int n)
void Add_ToRear(int n) 
boolean Add_ToSpecial(int coordi, int in)
boolean IsEmpty()
boolean Delete_Front() 
boolean Delete_Rear()
boolean Delete_Special(int coordi)
void PrintAll() 



Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:05
Processing time 0.0245 sec