【數據結構】線性表經常使用操做(C++)

線性表

順序表示

定義:

#define MAXSIZE 100 //最大長度
typedef struct
{
    ElemType * elem; //指向線性表的基地址
    int length; //線性表當前長度
}SqList;

相關函數:

C語言:<stdlib.h>

malloc(m)node

開闢 m 字節長度的地址空間,並返回這段空間的首地址。c++

sizeof(x)數組

計算變量 x 的長度。函數

free(p)指針

釋放指針 p 所指變量的存儲空間,即完全刪除一個變量。code

C++:new

int *p1 = new int;
//或者
int *p1 = new int(10);

//刪除
delete p1;

初始化線性表

參數用引用

Status InitList_Sq(SqList &L) //構造一個空的順序表L
{
    L.elem = new ElemType[MAXSIZE]; //爲順序表分配空間
    if(! L.elem)
    {
        exit(OVERFLOW); //存儲分配失敗
    }
    L.length = 0;
    return OK;
}

參數用指針

Status InitList_Sq(SqList *L) //構造一個空的順序表L
{
    L -> elem = new ElemType[MAXSIZE]; //爲順序表分配空間
    if( ! L -> elem)
    {
        exit(OVERFLOW); //存儲空間分配失敗
    }
    L -> length = 0;
    return OK;
}

銷燬線性表L

void DestroyList(SqList &L)
{
    if(L.elem)
    {
        delete[] L.elem; //釋放存儲空間
    }
}

清空線性表L

void ClearList(SqList &L)
{
    L.length = 0; //將線性表的長度置爲 0
}

判斷線性表L的長度

int GetLength(SqList L)
{
    return (L.length);
}

判斷線性表L是否爲空

int IsEmpty(SqList L)
{
    if(L.length == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

取值(根據位置 i 獲取相應位置數據元素的內容)

//獲取線性表L中的某個數據元素的內容
int GetElem(SqList L,int i,ElemType &e)
{
    if(i < 1 || i > length)
    {
        return ERROR;
    }
    //判斷 i 值是否合理,若不合理,返回ERROR
    e = L.elem[i-1]; //第 i-1 的單眼存儲着第 i 個數據
    return OK;
}

查找(根據指定數據獲取數據所在的位置)

//在線性表 L 中查找值爲 e 的數據元素
int LocateElem(SqList L,ElemType e)
{
    for( i = 0; i < L.length; i++)
    {
        if(L.elem[i] == e)
        {
            return i+1;
        }
    }
    return 0;
}

在線性表L中第i個元素以前插入數據元素e

Status ListInsert_Sq(SqList &L, int i, ElemType e)
{
    int j;
    if(i<1 || i > L.length+1)
    {
        return RERROR; // i 值不合法
    }
    if(L.length == MAXSIZE)
    {
        return ERROR; //當前存儲空間已滿。
    }
    for( j=L.length-1; j >= i-1; j--)
    {
        L.elem[j+1] = L.elem[j]; //插入位置及以後的元素後移
        L.elem[i-1] = e; //將新元素 e 放入第 i 個位置
        ++L.length; //表長增1
        return OK;
    }
}

將線性表 L 中第 i 個元素刪除

Status ListDelete_Sq(SqList &L, int i)
{
    if( (i<1) || (i > L.length) )
    {
        return ERROR;  // i 值不合法
    }
    for( j=i; j <= L.length-1; j++ )
    {
        L.elem[j-1] = L.elem[j]; //被刪除元素以後的元素前移
    }
    --L.length; //表長減 1
    return OK;
}

鏈式表示

存儲結構定義

typedef struct Lnode
{
    ElemType data; //數據域
    struct LNode *next; //指針域
} LNode,*LinkList;
//*LinkList 爲 Lnode 類型的指針

初始化

Struct InitList_L(LinkList &L)
{
    L = new LNode;
    L -> next = NULL;
    return OK;
}

銷燬

Status DestroyList_L(LinkList &L)
{
    LinkList p;
    while(L)
    {
        p = L;  
        L = L -> next;
        delete p;  
    }
     return OK;
}

清空

Status ClearList(LinkList & L)
{
  // 將L重置爲空表 
   LinkList p,q;
   p = L-> next;   //p指向第一個結點
   while(p)       //沒到表尾 
   {
       q = p -> next;
       delete p;
       p = q;
   }
   L -> next = NULL;   //頭結點指針域爲空 
   return OK;
}

求表長

//返回L中數據元素個數
int  ListLength_L(LinkList L)
{ 
    LinkList p;
    p = L -> next;  //p指向第一個結點
    i=0;    
    //遍歷單鏈表,統計結點數
    while(p)
    {
        i++;
        p=p->next;
    }
    return i;                             
 }

判斷表是否爲空

int ListEmpty(LinkList L)
{ 
    //若L爲空表,則返回1,不然返回0 
   if(L->next)
   {
       //非空 
       return 0;
   }
   else
   {
       return 1;
   }
}

取值(根據位置i獲取相應位置數據元素的內容)

//獲取線性表L中的某個數據元素的內容
Status GetElem_L(LinkList L,int i,ElemType &e)
{ 
    p = L -> next;
    j = 1; //初始化
    while( p && j < i )
    {
        //向後掃描,直到p指向第i個元素或p爲空 
        p = p -> next;
        ++j; 
    } 
    if(!p || j>i)
    {
        //第i個元素不存在 
        return ERROR;
    }
    e = p -> data; //取第i個元素 
    return OK; 
}//GetElem_L

在線性表L中查找值爲e的數據元素

LNode *LocateELem_L (LinkList L,Elemtype e) 
{
    //返回L中值爲e的數據元素的地址,查找失敗返回NULL
    p =L->next;
    while( p && p->data != e)
    {
        p=p->next;
    }        		
    return p; 	
} 

int LocateELem_L (LinkList L,Elemtype e) 
{
    //返回L中值爲e的數據元素的位置序號,查找失敗返回0 
    p = L->next;
    j = 1;
  	while(p && p->data != e)
    {
        p = p->next;
        j++;
    }        		
    if(p)
    {
        return j; 
    }
    else
    {
        return 0;
    }
}

在 L 中第 i 個元素以前插入數據元素e

Status ListInsert_L(LinkList &L,int i,ElemType e){ 
    p=L;
    j=0; 
    //尋找第i−1個結點 
    while( p && j < i−1 )
    {
        p = p->next;
        ++j;
    }
    //i大於表長 + 1或者小於1  
    if(!p||j>i−1)
    {
        return ERROR;	
    }
    s = new LNode; //生成新結點s 
    s->data = e; //將結點s的數據域置爲e 
    s->next = p->next; //將結點s插入L中 
    p->next = s; 
    return OK; 
}//ListInsert_L

將線性表L中第i個數據元素刪除

Status ListDelete_L(LinkList &L,int i,ElemType &e){
    p=L;j=0; 
    while(p->next &&j<i-1){                  //尋找第i個結點,並令p指向其前驅 
        p=p->next; ++j; 
    } 
    if(!(p->next)||j>i-1) return ERROR; //刪除位置不合理 
    q=p->next;                                        //臨時保存被刪結點的地址以備釋放 
    p->next=q->next; 	                  //改變刪除結點前驅結點的指針域 
    e=q->data; 	                                //保存刪除結點的數據域 
    delete q; 	                                //釋放刪除結點的空間 
 return OK; 
}//ListDelete_L

單鏈表的創建(前插法)

void CreateList_F(LinkList &L,int n){ 
     L=new LNode; 
      L->next=NULL; //先創建一個帶頭結點的單鏈表 
      for(i=n;i>0;--i){ 
        p=new LNode; //生成新結點 
        cin>>p->data; //輸入元素值 
        p->next=L->next;L->next=p; 	//插入到表頭 
     } 
}//CreateList_F

單鏈表的創建(尾插法)

void CreateList_L(LinkList &L,int n){ 
      //正位序輸入n個元素的值,創建帶表頭結點的單鏈表L 
      L=new LNode; 
      L->next=NULL; 	
      r=L; 	                                //尾指針r指向頭結點 
      for(i=0;i<n;++i){ 
        p=new LNode;	 	       //生成新結點 
        cin>>p->data;   		       //輸入元素值 
        p->next=NULL; r->next=p;       //插入到表尾 
        r=p; 	                                  //r指向新的尾結點 
      } 
}//CreateList_L

循環鏈表的合併

//假設 Ta、Tb 都是非空的單循環鏈表
LinkList Connect(LinkList Ta,LinkList Tb)
{
    p = Ta -> next; // p 存表頭結點
    Ta->next = Tb->next->next; // Tb 表頭連結 Ta 表尾
    delete Tb->next; //釋放 Tb 表頭結點
    Tb->next = p; //修改指針
    return Tb;
}

雙向鏈表

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

雙向鏈表的插入

Status ListInsert_DuL(DuLinkList &L,int i,ElemType e){
   if(!(p=GetElemP_DuL(L,i))) return ERROR;
    s=new DuLNode; 
   s->data=e;
   s->prior=p->prior;  
   p->prior->next=s;
   s->next=p;  
   p->prior=s;
   return OK;
}

雙向鏈表的刪除

Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e)
{
   if(!(p=GetElemP_DuL(L,i)))     return ERROR;
   e=p->data;
   p->prior->next=p->next;
   p->next->prior=p->prior;
   delete p; 
   return OK;
}

線性表的合併

void union(List &La, List Lb){
  La_len=ListLength(La);
  Lb_len=ListLength(Lb); 
  for(i=1;i<=Lb_len;i++){
      GetElem(Lb,i,e);
      if(!LocateElem(La,e)) 
           ListInsert(&La,++La_len,e);                     
  }
}
// O(ListLength(LB) x ListLength(LB))

有序的順序表合併

void MergeList_Sq(SqList LA,SqList LB,SqList &LC){ 
     pa=LA.elem;  pb=LB.elem;     //指針pa和pb的初值分別指向兩個表的第一個元素 
     LC.length=LA.length+LB.length;      	//新表長度爲待合併兩表的長度之和 
     LC.elem=new ElemType[LC.length];    	//爲合併後的新表分配一個數組空間 
     pc=LC.elem;                         		//指針pc指向新表的第一個元素 
     pa_last=LA.elem+LA.length-1; 	//指針pa_last指向LA表的最後一個元素 
     pb_last=LB.elem+LB.length-1; 	//指針pb_last指向LB表的最後一個元素 
     while(pa<=pa_last && pb<=pb_last){  	//兩個表都非空 
      if(*pa<=*pb) *pc++=*pa++;        	//依次「摘取」兩表中值較小的結點      
      else *pc++=*pb++;      } pa++;             //LB表已到達表尾
     while(pb<=pb_last)  *pc+
     while(pa<=pa_last)  *pc++=*+=*pb++;          //LA表已到達表尾 
}//MergeList_Sq 

//T(n)= O(ListLength(LB) + ListLength(LB))
//S(n)= O(n)

有序的鏈表合併

void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
   pa=La->next;  pb=Lb->next;
   pc=Lc=La;                    //用La的頭結點做爲Lc的頭結點 
   while(pa && pb){
      if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;}
      else{pc->next=pb; pc=pb; pb=pb->next;}
   pc->next=pa?pa:pb;      //插入剩餘段  
   delete Lb;                     //釋放Lb的頭結點}  
   }
}
相關文章
相關標籤/搜索