데이터 구조 학습 노트 - 선형 표 (양 방향 링크, 순환 링크)

14126 단어 데이터 구조
1. 머리말
본 고 는 양 방향 링크, 순환 링크 의 기본 적 인 조작 을 토론 한다.
2. 양 방향 링크
2.1 양 방향 링크 의 저장 구조
typedef struct DuLNode
{
	ElemType 	data;
	DuLNode 	*prior,*next;
}DuLNode,*DuLinkList;

2.2 양 방향 링크 의 기본 조작 (선두 결점)
(1) 선두 결점 의 양 방향 링크 L 중 i 번 째 위치 전에 요소 e 를 삽입 하고 i 의 합 법 치 는 1 ≤ i ≤ 표 장 + 1 이다.
Status ListInsert(DuLinkList L,int i,ElemType e)
{
	int 			j = 0;
	DuLinkList 		p = L, s;
	
	//    i-1   
	while (j < i-1 && p)
	{
		p = p->next;
		j++; 
	}
	
	if (!p || j > i-1)
		return ERROR;
	
	s = (DuLinkList)malloc(sizeof(DuLNode));
	if (!s) exit(OVERFLOW);
	
	s->data = e;
	
	//         1 
	if (!p->next)
	{
		s->next  = p->next;
		s->prior = p;
		p->next  = s;
	}
	//          1 
	else
	{
		s->next = p->next;
		p->next->prior = s;
		p->next  = s;
		s->prior = p;

	}
	return OK;
}

(2 ) 선두 결점 의 양 방향 링크 L 의 제 i 요 소 를 삭제 하고 i 의 합 법 치 는 1 ≤ i ≤ 표 장
//            L  i   ,i     1≤i≤  
Status ListDelete(DuLinkList L,int i,ElemType &e)
{
	int 			j = 0;
	DuLinkList 		p = L, q;
	
	//    i   ,  p     
	while (j < i-1 && p->next)
	{
		p = p->next;
		j++; 
	}
	
	if (!p->next || j > i-1)
		return ERROR;

	q = p->next;
	e = q->data;
	
	//         
	if (q->next)
	{
		p->next = q->next;
		q->next->prior = p;
	}
	//          
	else
	{
		p->next = q->next;		
	}
	
	free(q);
	return OK;
}

(3) 다른 기본 동작 은 매우 간단 합 니 다. 여기 서 더 이상 일일이 열거 하지 않 고 그 를 제 다운로드 자료 (dulist. cpp) 에 넣 고 main 함 수 를 포함 하여 이 기본 동작 들 을 테스트 합 니 다.
3. 순환 링크
3.1 꼬리 포인터 의 단일 순환 링크 를 설치한다.
//             12     
#include "ds.h"
using namespace std;

//#define TEST_ALGO

typedef 	int		ElemType;

typedef struct LNode{
	ElemType 		data;
	struct LNode	*next;
}LNode, *LinkList;


void InitList(LinkList &L);
void DestoryList(LinkList &L);
void ClearList(LinkList &L); //      L
Status ListEmpty(LinkList L);
int ListLength(LinkList L);
Status GetElem(LinkList L, int i, ElemType &e);
int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));
Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e);
Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e);
Status InsertList(LinkList &L, int i, ElemType e);  //      L
Status DeleteList(LinkList &L, int i, ElemType &e); //      L
void ListTraverse(LinkList L, void(*vi)(ElemType &e));

void MergeList(LinkList &La,LinkList Lb);

Status compare(ElemType e1, ElemType e2);
void print(ElemType &e);


void InitList(LinkList &L)
{ //     :         L
  L=(LinkList)malloc(sizeof(LNode)); //      ,  L      
  if(!L) //       
    exit(OVERFLOW);
  L->next=L; //         
}

void DestroyList(LinkList &L)
{ //     :     L
  LinkList q,p=L->next; // p     
  while(p!=L) //     
  {
    q=p->next;
    free(p);
    p=q;
  }
  free(L);
  L=NULL;
}

void ClearList(LinkList &L) //   L
{ //     :   L   。    : L     
  LinkList p,q;
  L=L->next; // L     
  p=L->next; // p       
  while(p!=L) //     
  {
    q=p->next;
    free(p);
    p=q;
  }
  L->next=L; //           
}

Status ListEmpty(LinkList L)
{ //     :   L   。    : L   ,   TRUE,    FALSE
  if(L->next==L) //  
    return TRUE;
  else
    return FALSE;
}

int ListLength(LinkList L)
{ //     :L   。    :  L       
  int i=0;
  LinkList p=L->next; // p     
  while(p!=L) //     
  {
    i++;
    p=p->next;
  }
  return i;
}

Status GetElem(LinkList L,int i,ElemType &e)
{ //   i      ,    e   OK,    ERROR
  int j=1; //    ,j    
  LinkList p=L->next->next; // p       
  if(i<=0||i>ListLength(L)) //  i      
    return ERROR;
  while(jnext;
    j++;
  }
  e=p->data; //   i   
  return OK;
}

int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ //     :   L   ,compare()         
  //     :  L  1  e    compare()        。
  //                      ,     0
  int i=0;
  LinkList p=L->next->next; // p       
  while(p!=L->next)
  {
    i++;
    if(compare(p->data,e)) //     
      return i;
    p=p->next;
  }
  return 0;
}

Status PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e)
{ //     :   L   
  //     : cur_e L     ,      ,  pre_e      ,
  //                 ,pre_e   
  LinkList q,p=L->next->next; // p       
  q=p->next;
  while(q!=L->next) // p    
  {
    if(q->data==cur_e)
    {
      pre_e=p->data;
      return TRUE;
    }
    p=q;
    q=q->next;
  }
  return FALSE; //     
}

Status NextElem(LinkList L,ElemType cur_e,ElemType &next_e)
{ //     :   L   
  //     : cur_e L     ,       ,  next_e      ,
  //                 ,next_e   
  LinkList p=L->next->next; // p       
  while(p!=L) // p    
  {
    if(p->data==cur_e)
    {
      next_e=p->next->data;
      return TRUE;
    }
    p=p->next;
  }
  return FALSE; //     
}

Status ListInsert(LinkList &L,int i,ElemType e) //   L
{ //  L  i         e
  LinkList p=L->next,s; // p     
  int j=0;
  if(i<=0||i>ListLength(L)+1) //     i       
    return ERROR;
  while(jnext;
    j++;
  }
  s=(LinkList)malloc(sizeof(LNode)); //      
  s->data=e; //   L 
  s->next=p->next;
  p->next=s;
  if(p==L) //      
    L=s;
  return OK;
}

Status ListDelete(LinkList &L,int i,ElemType &e) //   L
{ //   L  i   ,  e    
  LinkList p=L->next,q; // p     
  int j=0;
  if(i<=0||i>ListLength(L)) //  i      
    return ERROR;
  while(jnext;
    j++;
  }
  q=p->next; // q       
  p->next=q->next;
  e=q->data;
  if(L==q) //         
    L=p;
  free(q); //        
  return OK;
}

void ListTraverse(LinkList L,void(*vi)(ElemType &))
{ //     :L   。    :   L           vi()
  LinkList p=L->next->next; // p      
  while(p!=L->next) // p      
  {
    vi(p->data);
    p=p->next;
  }
  printf("
"); } // void MergeList(LinkList &La,LinkList Lb) { // Lb La , La LinkList p=Lb->next; Lb->next=La->next; La->next=p->next; free(p); La=Lb; } Status compare(ElemType a, ElemType b) { if (a == b) return TRUE; else return FALSE; } void print(ElemType &e) { printf("%d ", e); } int main() { LinkList L; ElemType e; int j; Status i; InitList(L); // L i=ListEmpty(L); printf("L i=%d(1: 0: )
",i); ListInsert(L,1,3); // L 3,5 ListInsert(L,2,5); i=GetElem(L,1,e); j=ListLength(L); printf("L =%d, 1 %d。
",j,e); printf("L :"); ListTraverse(L,print); PriorElem(L,5,e); // 5 printf("5 %d。
",e); NextElem(L,3,e); // 3 printf("3 %d。
",e); printf("L %d(1: 0: )
",ListEmpty(L)); j=LocateElem(L,5,compare); if(j) printf("L %d 5。
",j); else printf(" 5
"); i=ListDelete(L,2,e); printf(" L 2 :
"); if(i) { printf(" %d, L :",e); ListTraverse(L,print); } else printf(" !
"); ClearList(L); printf(" L ,L :%d(1: 0: )
",ListEmpty(L)); DestroyList(L); // int n=5,k; LinkList La,Lb; InitList(La); for(k=1;k<=n;k++) ListInsert(La,k,k); printf("La="); // La ListTraverse(La,print); InitList(Lb); for(k=1;k<=n;k++) ListInsert(Lb,1,k*2); printf("Lb="); // Lb ListTraverse(Lb,print); MergeList(La,Lb); printf("La+Lb="); // ListTraverse(La,print); return 0; }

3.2 양 방향 순환 링크 (선두 노드)
//                 (14 )

#include "ds.h"
using namespace std;

typedef 	int		ElemType;

typedef struct DuLNode
{
	ElemType 	data;
	DuLNode 	*prior,*next;
}DuLNode,*DuLinkList;

void InitList(DuLinkList &L);
void DestroyList(DuLinkList &L); 
void ClearList(DuLinkList L);
Status ListEmpty(DuLinkList L);
int ListLength(DuLinkList L);
Status GetElem(DuLinkList L,int i,ElemType &e);
DuLinkList GetElemP(DuLinkList L,int i); //   
int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType));
Status PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e);
Status NextElem(DuLinkList L,ElemType cur_e,ElemType &next_e);
Status ListInsert(DuLinkList L,int i,ElemType e);
Status ListDelete(DuLinkList L,int i,ElemType &e);
void ListTraverse(DuLinkList L,void(*vi)(ElemType));
void ListTraverseBack(DuLinkList L,void(*print)(ElemType));

int compare(ElemType a,ElemType b);
void print(ElemType c);

void InitList(DuLinkList &L)
{ //           L
  L=(DuLinkList)malloc(sizeof(DuLNode));
  if(L)
    L->next=L->prior=L;
  else
    exit(OVERFLOW);
}

void DestroyList(DuLinkList &L)
{ //     :        L
  DuLinkList q,p=L->next; // p       
  while(p!=L) // p    
  {
    q=p->next;
    free(p);
    p=q;
  }
  free(L);
  L=NULL;
}

void ClearList(DuLinkList L) //    L
{ //     :L   。    : L     
  DuLinkList q,p=L->next; // p       
  while(p!=L) // p    
  {
    q=p->next;
    free(p);
    p=q;
  }
  L->next=L->prior=L; //               
}

Status ListEmpty(DuLinkList L)
{ //     :   L   。    : L   ,   TRUE,    FALSE
  if(L->next==L&&L->prior==L)
    return TRUE;
  else
    return FALSE;
}

int ListLength(DuLinkList L)
{ //     :L   。    :  L       
  int i=0;
  DuLinkList p=L->next; // p       
  while(p!=L) // p    
  {
    i++;
    p=p->next;
  }
  return i;
}

Status GetElem(DuLinkList L,int i,ElemType &e)
{ //   i      ,    e   OK,    ERROR
  int j=1; // j    
  DuLinkList p=L->next; // p       
  while(p!=L&&jnext;
    j++;
  }
  if(p==L||j>i) //  i      
    return ERROR;
  e=p->data; //   i   
  return OK;
}

int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{ //     :L   ,compare()         
  //     :  L  1  e    compare()        。
  //                      ,     0
  int i=0;
  DuLinkList p=L->next; // p   1   
  while(p!=L)
  {
    i++;
    if(compare(p->data,e)) //          
      return i;
    p=p->next;
  }
  return 0;
}

Status PriorElem(DuLinkList L,ElemType cur_e,ElemType &pre_e)
{ //     : cur_e L     ,      ,  pre_e      ,
  //             ,      ,pre_e   
  DuLinkList p=L->next->next; // p   2   
  while(p!=L) // p    
  {
    if(p->data==cur_e)
    {
      pre_e=p->prior->data;
      return TRUE;
    }
    p=p->next;
  }
  return FALSE;
}

Status NextElem(DuLinkList L,ElemType cur_e,ElemType &next_e)
{ //     : cur_e L     ,       ,  next_e      ,
  //                 ,next_e   
  DuLinkList p=L->next->next; // p   2   
  while(p!=L) // p    
  {
    if(p->prior->data==cur_e)
    {
      next_e=p->data;
      return TRUE;
    }
    p=p->next;
  }
  return FALSE;
}

DuLinkList GetElemP(DuLinkList L,int i) //   
{ //      L    i      。i 0,        。  i      ,
  //   NULL(  2.18、2.19      )
  int j;
  DuLinkList p=L; // p     
  if(i<0||i>ListLength(L)) // i    
    return NULL;
  for(j=1;j<=i;j++)
    p=p->next;
  return p;
}

Status ListInsert(DuLinkList L,int i,ElemType e)
{ //              L  i         e,i     1≤i≤  +1
  //     2.18,        +1         
  DuLinkList p,s;
  if(i<1||i>ListLength(L)+1) // i    
    return ERROR;
  p=GetElemP(L,i-1); //  L    i          p
  if(!p) // p=NULL,  i         (      1      )
    return ERROR;
  s=(DuLinkList)malloc(sizeof(DuLNode));
  if(!s)
    return OVERFLOW;
  s->data=e;
  s->prior=p; //   i-1       
  s->next=p->next;
  p->next->prior=s;
  p->next=s;
  return OK;
}

Status ListDelete(DuLinkList L,int i,ElemType &e) //   2.19
{ //               L  i   ,i     1≤i≤  
  DuLinkList p;
  if(i<1) // i    
    return ERROR;
  p=GetElemP(L,i);  //  L    i        p
  if(!p) // p=NULL,  i      
    return ERROR;
  e=p->data;
  p->prior->next=p->next;
  p->next->prior=p->prior;
  free(p);
  return OK;
}

void ListTraverse(DuLinkList L,void(*visit)(ElemType))
{ //         L      ,             visit()
  DuLinkList p=L->next; // p     
  while(p!=L)
  {
    visit(p->data);
    p=p->next;
  }
  printf("
"); } void ListTraverseBack(DuLinkList L,void(*visit)(ElemType)) { // L , visit()。 DuLinkList p=L->prior; // p while(p!=L) { visit(p->data); p=p->prior; } printf("
"); } int compare(ElemType a,ElemType b) { if (a == b) return TRUE; else return FALSE; } void print(ElemType c) { printf("%d ", c); } int main() { DuLinkList L; int i,n; Status j; ElemType e; InitList(L); for(i=1;i<=5;i++) ListInsert(L,i,i); // i i printf(" :"); ListTraverse(L,print); // printf(" :"); ListTraverseBack(L,print); // n=2; ListDelete(L,n,e); // n printf(" %d , %d, :",n,e); ListTraverse(L,print); // printf(" %d
",ListLength(L)); printf(" :%d(1: 0: )
",ListEmpty(L)); ClearList(L); // printf(" , :%d(1: 0: )
",ListEmpty(L)); for(i=1;i<=5;i++) ListInsert(L,i,i); // 5 ListTraverse(L,print); // n=3; j=GetElem(L,n,e); // n e if(j) printf(" %d %d
",n,e); else printf(" %d
",n); n=4; i=LocateElem(L,n,compare); if(i) printf(" %d %d
",n,i); else printf(" %d
",n); j=PriorElem(L,n,e); if(j) printf("%d %d
",n,e); else printf(" %d
",n); j=NextElem(L,n,e); if(j) printf("%d %d
",n,e); else printf(" %d
",n); DestroyList(L); return 0; }

좋은 웹페이지 즐겨찾기