1. 程式人生 > >線性表插入和刪除——程式例項

線性表插入和刪除——程式例項

順序實現

.h檔案 此檔案為方法    
#ifndef SQLIST_H_INCLUDED     
#define SQLIST_H_INCLUDED     
#include "ds.h" //for Status,OK ...     
#ifndef ElemType     
#define ElemType int /* 資料元素型別預設為 int */     
#define ELEMTYPE_TAG     
#endif  

   
/**********************************************************     
*  順序表的儲存結構定義      
***********************************************************/
#define LIST_INIT_SIZE 100 /* 儲存空間初始分配容量 */     
#define LISTINCREMENT 10 /* 儲存空間分配的增量 */     
typedef struct {     
    ElemType *elem;    //儲存空間基址     
    int length;        //當前長度      
    int listsize;      //當前已分配的儲存空間(元素個數)      
} SqList;  

   
/**********************************************************     
*  順序表的基本操作宣告     
***********************************************************/
//建立並初始化為空表      
Status InitList(SqList &L);     
//銷燬整個表(從此之後不再可用)      
Status DestroyList(SqList &L);     
//將表L置空      
Status ClearList(SqList &L);     
//判斷表L是否為空表      
bool ListEmpty(SqList L);     
//求表L的長度      
int ListLength(SqList L);     
//取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR      
Status GetElem(SqList L, int i, ElemType &e); 
    
template <typename T> bool equal(T a, T b)     
{     
    return a==b;     
} 
    
//在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0      
//    compare(a,b) 為比較函式,匹配時返回true,否則返回false      
//                 這裡預設使用equal進行比較   
   
int LocateElem(SqList L, ElemType e,      
      bool (*compare)(ElemType,ElemType)=equal<ElemType>);     
//在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR     
Status ListInsert(SqList &L, int i, ElemType e);     
//刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR      
Status ListDelete(SqList &L, int i, ElemType &e);     
//遍歷表L,對每個元素呼叫visit(x).      
Status ListTraverse(SqList L, Status (*visit)(ElemType));     
/**********************************************************     
*  順序表的基本操作的實現     
***********************************************************/
//建立並初始化為空表      
Status InitList(SqList &L)     
{     
    // TODO (#1#): 建立空表     
    L.elem=(ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));     
    if(!L.elem)exit(OVERFLOW);     
    L.length=0;     
    L.listsize=LIST_INIT_SIZE;     
    return OK;     
    //-------------------------------------     
}     
//銷燬整個表(從此之後不再可用)      
Status DestroyList(SqList &L)     
{     
    free(L.elem);     
    return OK;     
    //-------------------------------------     
}     
//將表L置空      
Status ClearList(SqList &L)     
{     
    // TODO (#1#): 清空表     
    L.length=0;     
    return OK;     
    //-------------------------------------     
}     
//判斷表L是否為空表      
bool ListEmpty(SqList L)     
{     
    // TODO (#1#): 順序表判空      
    if(L.length==0)     
        return TRUE;     
    else
    return FALSE;     
    //-------------------------------------     
}     
          
//求表L的長度      
int ListLength(SqList L)     
{     
    // TODO (#1#): 求順序表長度     
    return  L.length;     
  
    //-------------------------------------     
}     
          
//取表L中的第i個元素,並用e返回. 操作成功返回OK,失敗時返回ERROR      
Status GetElem(SqList L, int i, ElemType &e)     
{     
    // TODO (#1#): 取元素     
    if(ListEmpty(L))     
    {     
        printf("線性表L為空n");     
        return ERROR;     
    }      
    if(i<1||i>L.length)     
    {     
        printf("不存在%d位置的元素n",i);     
        return ERROR;     
    }     
    e=L.elem[i-1];     
    return OK;      
    //-------------------------------------     
}     
          
//在表L中定位元素e首次出現的位置. 操作成功返回位序,失敗時返回0      
//    compare(a,b) 為比較函式,匹配時返回true,否則返回false      
int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType,ElemType))     
{     
    // TODO (#1#): 在表中定位元素e,用compare(a,b)匹配元素     
    for (int j=0; j<L.length; j++)     
        if ( compare(L.elem[j],e) )  return j+1;     
    return 0;     
    //-------------------------------------     
}     
          
          
//在表L中插入第i個元素e. 操作成功返回OK,失敗時返回ERROR     
Status ListInsert(SqList &L, int i, ElemType e)     
{     
    // TODO (#1#): 在連結串列中插入元素     
    if(i<1 || i>L.length+1)     
        return ERROR;     
     if (L.length >= L.listsize) //判讀儲存空間是否已滿     
    {     
        ElemType * newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));     
        if (!newbase)     
            exit(OVERFLOW);     
        L.elem = newbase;     
        LL.listsize = L.listsize + LISTINCREMENT;     
    }     
    ElemType *q = &(L.elem[i - 1]); //q指向第i個元素     
    ElemType *p;                     //p指向最後一個元素     
          
    for (p= &(L.elem[L.length - 1]); p >= q; p--) //從最後一個位置開始移動     
    {     
        *(p + 1) = *p;     
    }     
          
    *q = e;     
    L.length++;     
    return ERROR;     
    //-------------------------------------     
}     
          
//刪除表L中第i個元素,結果用e返回. 操作成功返回OK,失敗時返回ERROR      
Status ListDelete(SqList &L, int i, ElemType &e)     
{     
    // TODO (#1#): 在順序表中刪除元素     
if (L.length == 0) //判斷表是否為空     
    {     
        printf("表為空n");     
        return ERROR;     
    }     
          
    if (i < 1 || i > L.length) //判斷刪除位置是否合法     
    {     
        printf("刪除位置不合法n");     
        return ERROR;     
    }     
          
    ElemType *p = &(L.elem[i - 1]); //p指向待刪除的元素     
    e = *p;     
    ElemType *q = &(L.elem[L.length - 1]);     
    //ElemType *q = L->elem + L->length - 1; //q指向最後一個元素     
    for (pp = p + 1; p <= q; p++) //p從待刪除的後一個元素開始,直到最後一個元素,每個元素一次向前移動一個位置     
    {     
        *(p - 1) = *p;     
    }     
          
    L.length--; //最後,線性表長度減一     
          
    return OK;     
    //-------------------------------------     
}     
          
//遍歷表L,對每個元素呼叫visit(x).      
Status ListTraverse(SqList L, Status (*visit)(ElemType))     
{     
    // TODO (#1#): 遍歷順序表      
    for (int j=0; j<L.length; j++)     
        if ( ! visit(L.elem[j]) )  return ERROR;     
    return OK;     
    //-------------------------------------     
}
.cpp檔案 此檔案為主函式    
#ifdef ELEMTYPE_TAG     
#undef ElemType     
#undef ELEMTYPE_TAG     
#endif     
#endif  // SQLIST_H_INCLUDED     
#include <stdio.h>     
#include <stdlib.h>     
#include "ds.h"     
#define ElemType int                 //資料元素的型別      
Status print(ElemType e);            // 列印資料元素的方法     
bool equal(ElemType a, ElemType b);  //比較兩個元素相等的方法      
#include "sqlist.h"     
//列印順序表內容      
void PrintLinkList(SqList L);     
int main()     
{     
    SqList L;     
              
    //1)初始化順序表      
    InitList(L);     
              
    //2)插入一些元素: 12,23,34,45     
    ListInsert(L,1,12);     
    ListInsert(L,1,23);     
    ListInsert(L,1,34);     
    ListInsert(L,1,45);     
              
    //3)列印順序表資訊      
    printf("n開始時順序表內容n");     
    PrintLinkList(L);     
    printf("ListLength(L) : %dn", ListLength(L));     
    printf("ListEmpty(L)  : %dn", ListEmpty(L));     
              
    //4)順序表插入      
    printf("n請輸入一個元素:");      
    ElemType x;     
    read(x);     
    printf("插入開頭:");     
    ListInsert(L,1,x);     
    PrintLinkList(L);     
    printf("插入末尾:");      
    ListInsert(L,ListLength(L)+1,x);     
    PrintLinkList(L);     
              
    //5)順序表刪除     
    printf("n請選擇刪除第i(1..%d)個元素:", ListLength(L));     
    int i;     
    read(i);     
    ElemType e;      
    if ( ListDelete(L,i,e)==OK ) {     
        Status print(ElemType e);  //宣告print(e)函式      
                  
        printf("刪除"); print(e);     
        printf("成功n");     
    } else
        printf("刪除失敗.n");     
    printf("順序表內容:");     
    PrintLinkList(L);     
              
    //6)元素定位     
    printf("n請輸入一個元素以便定位:");     
    read(x);     
    i = LocateElem(L,x);     
    if ( i!=0 ) {     
        printf("該元素是表中的第%d個元素.n",i);     
    } else
        printf("該元素在表中不存在.n");      
              
    //7)清空順序表     
    ClearList(L);     
    printf("n最後順序表內容n");     
    PrintLinkList(L);     
    printf("ListLength(L) : %dn", ListLength(L));     
    printf("ListEmpty(L)  : %dn", ListEmpty(L));     
               
    //8)銷燬順序表      
    DestroyList(L);     
              
    system("PAUSE");     
    return 0;     
}     
          
// 列印資料元素的方法      
Status print(ElemType e)     
{     
    printf("%5d",e);     
    return OK;     
}     
          
//比較兩個元素相等的方法     
bool equal(ElemType a, ElemType b)     
{     
    return a==b;     
}     
          
//列印順序表內容      
void PrintLinkList(SqList L)     
{     
    ListTraverse(L,print); //遍歷順序表並print()每個元素      
    printf("n");     
}