鏈表應用舉例

例一:求表長
設一個移動工作指針p和一個計數器j,初始時p=L->next,J=0,若p非空,則計數器加1,並將指針下移一個位置,直到達鏈表尾,算法描述如下:

int LinkListLen(LinkList L)
{
//求帶頭結點的單鏈表L的長度
    LNode *p
    int j=0;
    p=L->next;//p指向第一個結點
    while(p){j++;p=p->next;}//p指向第j個節點
    return j;
}

例二:編寫一個將單循環鏈表逆置的算法
解: 設置一個工作指針p,初始指向單循環鏈表L的第一結點,將L的next域指向L,即建立一個空單循環鏈表,然後採用頭插法將所有結點插入到單循環鏈表L中,算法如下:

int conrrayCirLinkList(CirLinkList &L){//頭插法建立
    LNode *p ,*q;
    p=->next;
    L->next=L;//建立空單循環鏈表
    while(p!=L)
    {
        q=p;
        p=p->next;
        q->next=L->next;
        L->next=q;
    }
    return OK;
}

例三:一直有兩個帶頭結點的循環單鏈表,設計一個算法,用最快速度將這兩個表合成一個帶頭結點的循環單鏈表。要求時間複雜度O(1),且佔用輔助空間最小。

解: 根據要求,只有設尾指針的單循環鏈表才能實現。算法如下:

void UnionCirLinkList(CirLinkList &Ls,CirLinkList &Lb){
//La和Lb是帶頭結點的單循環鏈表
    LNode *q;
    q=Lb->next;//q指向Lb的頭結點
    Lb->next=La->next;//Lb的後繼結點爲La的頭結點
    La->next=q->next;//La的後繼結點爲原Lb的第一個元素結點
    delete q;//釋放原Lb的頭結點
    }

例四:
將兩個有序表La和Lb歸併成一個有序表,要求不能另設新空間。
解: 算法如下

void mergelist(LinkList &La,LinkList &Lb,LinkList &Lb)
{
LinkList pa,pb,pc;
pa=La->next;pb=Lb->next;
Lc=pc=La;
while(pa&&pb)
{
    if(pa->data<=pb->data)
    {
        pc->next=pa;
        pc=pa;
        pa=pc->next;        
    }
    else
    {
        pc->next=pb;
        pc=pb;
        pb=pb->next;
    }
}
if(!pa)pc->next=pb;
if(!pb)pc->next=pa;
delete Lb;
}

例五: 一元稀疏多項式相加。
解: 鏈表的存儲結構如下:

typedef struct
{
    float coef;//係數
    int expn;//指數
}term,ElemType;
typedef struct Lnode
{
    Elemtype data;
    struct Lnode *next;
}Lnode,*LinkList

對於兩個一元多項式所有指數相同的項,將對應係數相加,若其和不爲0,則構成“和多項式”中的一項;對兩個一元多項式中指數不同的項,則分別復抄到“和多項式”中。
算法描述如下:

void addlist(LinkList &La,LinkList &Lb)
{
    pa=La->next;
    pb=Lb->next;
    pc=pa;//指向鏈表當前結尾點
    while(pa&&pb)
    {
        if(pa->data.expn<pb->data.expn)
        {
            pc->next=pa;
            pc=pa;
            pa=pa->next;
        }
        else
            if(pa->data.expn<pb->data.expn)
            {
                pc->next=pb;
                pc=pb;
                pb=pa->next;
            }
    else
    {
        sum=pa->data.coef + pb->data.coef;
        if(sum==0)
        {
            p=pa;
            pa=pa->next;
            delete p;
            p=pb;
            pb=pb->next;
            delete p;
        }
        else
        {
            pa->data.coef=sum;
            pc->next=pa;
            pc=pa;
            pa=pa->next;
            p=pb;
            pb=pb->next;
            delete p;
        }
    }
    }
    if(pa)pc->next=pa;
    if(pb)pc->next=pb;
    delete Lb;//釋放Lb頭指針
}

例六: 設L是帶頭結點的頭指針,試編寫算法,按照遞增次序輸出單鏈表各節點的數據元素,並釋放所佔的存儲空間。要求不允許使用數組作爲輔助空間。
解: 應對鏈表進行遍歷,每次遍歷中查找出整個鏈表的最小元素,輸出並釋放頭結點所佔空間。算法如下:

void deleteMin(LinkList &L)
{
    LNode *pre,*p,*q;
    while(L->next)
    {
        pre=L;
        p=L->next;//p爲工作指針
        while(p->next)
            if(p->next->data < pre->next->data)
            {
                pre=p;
                p=p->next;
            }
            else
                p=p->next;
            printf("%d",pre->next->data);//輸出元素最小結點的數據
            q=pre->next;
            pre->next=q->next;
            delete (q);//刪除元素最小結點
    }
    delete (L);//釋放頭結點
}

例七: 有一個雙向鏈表從第二個結點到表尾遞增有序。試編寫算法,將第一個結點刪除並插入到適當位置,使整個鏈表遞增有序。
解: 算法如下:

void insertnode(DuLinkLinst &L)
{
    DuNode *p,*q,*r;
    p=L->next;
    L->next=p->next;
    p->next->prior=L;
    q=L->next;//q爲工作指針
    r=L;//r爲q的前驅
    while (q&&q->data < p->data)
    {
        r=q;
        q=q->next;
    }
    if(q)
    {
        q->prior->next=p;
        p->prior=q->prior;
        p->next=q;
        q->prior=p;
    }
    else
    {//插在尾部
        p->next=r->next;
        r->next=q;
        p->prior=r;
    }
}

終於要下雨了,熱成狗了!

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