1.2順序線性表的歸併

18.12.23

#include<stdio.h>
#include<stdlib.h>
#define LIST_INITSIZE 100  //線性表存儲空間的初始分配量
#define LIST_INCREMENT 10  //線性表存儲空間空間的分配增量 
#define OK 1
#define ERROR 0
#define OVERFLOW -1//溢出 
typedef int ElemType;      //設元素類型爲int 
typedef struct
{
    ElemType *elem;       //存儲空間基址
    int length;           //當前長度
    int listsize;         //當前分配的存儲容量 (以sizeof(ElemType)爲單位)
}SeqList;                 //定義線性表的類型 
int InitList (SeqList &L) //線性表的初始化,構造一個空的線性表L 
/*形參L爲引用型變量,&爲取地址符(此處爲引用傳遞),形參相當於是實參的“別名”,對形參的操作其實就是對實參的操作。 
用了引用變量後,就不再爲形參開闢內存,所有操作都是直接修改實參變量。 */ 
{
    L.elem = (ElemType *)malloc(LIST_INITSIZE * sizeof(ElemType));
    if(! L.elem)          // L.elem = NULL時,NULL(值爲0)爲空指針 
        exit(OVERFLOW);   //存儲分配失敗,結束程序
    L.length = 0;         //空表長度爲0
    L.listsize = LIST_INITSIZE;  //初始化存儲容量
    return OK; 
}
int CreatList(SeqList &L)
{
    int i;
    scanf("%d",&L.length);
    for(i = 0;i < L.length;++i)
    {
        scanf("%d",L.elem + i);  
    }
}
int InsertList(SeqList &L,int i,ElemType e)
{    
    //在順序線性表L中第i個位置之前插入新的e
    //i的合法值爲1<=i<=L.length + 1
    ElemType *newbase,*q,*p;
    if(i<1 || i > L.length + 1)
        return  ERROR;   //i的值不合法
    if(L.length >= L.listsize) //當前存儲空間已滿,增加分配 
    {
         newbase = (ElemType*)realloc(L.elem,(L.listsize + LIST_INCREMENT) * sizeof(ElemType));//重新分配存儲空間 
        if(! L.elem)
            exit(OVERFLOW);
        L.elem = newbase; //新基址
        L.listsize += LIST_INCREMENT;   //增加存儲容量 
    } 
    q = &(L.elem[i-1]);   //q爲插入的地址 
    for(p = &(L.elem[L.length - 1]);p >= q;--p)  //p初始值爲表尾元素的位置 
        *(p+1) = *p;      //插入位置及之後的元素右移
    *q = e;           //插入e
    ++L.length;       //表長增1
    return OK; 
}
int DeleteList(SeqList &L,int i,ElemType &e)//在順序線性表L中刪除第i個元素,並用e返回其值

    ElemType *p,*q;
    if(i<1 || i > L.length)
        return  ERROR;   //i的值不合法
    p = &(L.elem[i-1]);  //p 爲被刪除元素的位置, p = L.elem + i - 1
    e = *p;              //被刪除元素的值賦給e
    q = L.elem + L.length - 1;  //表尾元素的位置
    for(++p;p <= q;++p)  //p=p+1初始 
        *(p-1) = *p;     //被刪除元素之後的元素左移
    --L.length;          //表長減一
    return OK;
}
/*
int Locate_List(SeqList L,ElemType e,int (*compare)(ElemType,ElemType))
//在順序線性表L中查找第1個值與e滿足compare()的元素的位序 
//若找到,則返回其在L中的位序,否則返回0 
{
    int i;
    ElemType *p;
    i = 1;              //i的初值爲第1個元素的位序
    p = L.elem;         //p的初值爲第1個元素的存儲位置
    while(i <= L.length && !(*compare)(*p++,e))  //*p++先以原值帶入,compare爲函數指針 
        ++i;          //遍歷查找
    if(i <= L.length) 
        return i--;
    else 
        return 0; 
}
*/
void MergeList(SeqList La,SeqList Lb,SeqList &Lc)
{
    //已知順序線性表La和Lb的元素按值非遞減排列
    //歸併La和Lb得到新的順序線性表Lc,Lc的元素也按值非遞減排列
    ElemType *pa,*pb,*pc,*pa_last,*pb_last;
    pa = La.elem;
    pb = Lb.elem;
    Lc.listsize = Lc.length = La.length + Lb.length;
    pc = Lc.elem =  (ElemType *)malloc(Lc.listsize * sizeof(ElemType));
    if(! Lc.elem)         //存儲分配失敗 
        exit(OVERFLOW);
    pa_last = La.elem + La.length - 1; //相當於&La.elem[La.length - 1],最後一個元素的存儲位置 
    pb_last = Lb.elem + Lb.length - 1;
    while(pa <= pa_last && pb <= pb_last)//歸併,遞增排列,其中一個順序表插入完結束循環 
    {
        if(*pa <= *pb)    //小值先進 
            *pc++ = *pa++;  //*(pc++) = *(pa++),先使用原值進行運算,相當於*pc = *pa,pc++,pa++
        else 
            *pc++ = *pb++;
  
    }
    while(pa <= pa_last) 
        *pc++ = *pa++;      //Lb先完全插入,之後插入La的剩餘元素
    while(pb <= pb_last)
        *pc++ = *pb++;      //La先完全插入,之後插入Lb的剩餘元素  

void Del_Repe(SeqList &L,SeqList &E)   //刪除有序順序線性表(遞增或遞減)中重複元素,並返回其值 
{
    int i; 
    for(i = 1;i <= L.length -1;++i)  //L.length 與Delete函數對應 
    {
        if(L.elem[i-1] == L.elem[i])
        {
            DeleteList(L,i,*(E.elem+E.length));//調用刪除函數,刪除重複元素且表長減一 
            E.length++;
            i--;  //Delete函數時表長減一,i之後元素左移,需重新判斷i上的數是否重複 
        }
    }

void PrintList(SeqList L)  //輸出順序線性表 
{
    int i = 0;
    for(i = 0;i < L.length;++i)
        printf("%d ",*L.elem++);    //printf("%d",*L.elem),L.elem++,因爲L是形參,L.elem自增不影響實參 
    printf("\n");
}
main()
{
    SeqList La,Lb,Lc,E;
    ElemType e;
    int i;
    InitList(La);           //引用傳遞,函數內直接改變實參變量
    InitList(Lb);           //線性表的初始化,分配動態存儲空間 
    InitList(E);
    CreatList(La);
    CreatList(Lb);
    MergeList(La,Lb,Lc);
    PrintList(Lc);
    Del_Repe(Lc,E);
    PrintList(Lc);
    PrintList(E);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章