算法導論 10.2-6 帶哨兵的雙向鏈表合併兩個不相交的集合

/*
O(1)合併S1、S2。S1、S2集合不相交。
*/
/*需要能在O(1)時間內訪問到S1、S2的頭和尾的鏈表:
帶頭結點和尾結點的單鏈表;雙向循環鏈表。*/
//帶哨兵的雙向鏈表:S1頭接S2尾,S2頭接S1尾。

#include<stdio.h>
#include<stdlib.h>
typedef struct NODE{
    struct NODE*prev;char key;struct NODE*next;
}NODE;
NODE*NIL1=NULL,*NIL2=NULL;//兩個雙鏈表的哨兵結點。
void insert(NODE**NIL,NODE*p)//將p插入到L首端
{
    (*NIL)->next->prev=p;
    p->next=(*NIL)->next;
    (*NIL)->next=p;
    p->prev=*NIL;
}
NODE* createnode(char key)
{
    NODE*p=(NODE*)malloc(sizeof(NODE));
    if(!p){
        puts("memory exhausted.");exit(1);
    }
    p->key=key;
    return p;
}
void traverse(NODE* NIL)
{
    NODE*p;
    for(p=NIL->next;p!=NIL;p=p->next)
        putchar(p->key);
    putchar(' ');putchar(' ');
    for(p=NIL->prev;p!=NIL;p=p->prev)
        putchar(p->key);
    putchar('\n');
}
void union1()//合併後成爲NIL1
{
    NIL1->next->prev=NIL2->prev;
    NIL2->prev->next=NIL1->next;
    //putchar(NIL1->prev->prev->next->key);putchar(NIL1->prev->prev->key);
    NIL1->next=NIL2->next;
    NIL2->next->prev=NIL1;
    free(NIL2);
}
int main(void)
{
    //創建2個空鏈表
    NIL1=createnode(('#'));
    NIL1->next=NIL1->prev=NIL1;
    NIL2=createnode(('#'));
    NIL2->next=NIL2->prev=NIL2;

    int i;
    for(i=0;i<10;i++)
        insert(&NIL1,createnode('0'+i));
    for(i=0;i<26;i++)
        insert(&NIL2,createnode('a'+i));

    union1();
    traverse(NIL1);
    return 0;
}
發佈了47 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章