1. 程式人生 > 實用技巧 >線性表之單鏈表

線性表之單鏈表

在學完線性表之後,總結一下順序表的優缺點

優點

  • 無須為元素之間的邏輯結構增添額外的儲存空間,自成一體。
  • 隨機存取,十分方便。

缺點

  • 空間利用率不高,容易造成“碎片”。
  • 插入刪除操作需要移動大量的元素。
  • 當線性表的長度變化較大時,難以確定儲存空間的容量。

而單鏈表可以很好的彌補順序表的這些缺點。

一、實現方式

typedef int Elemtype;
typedef struct Node
{
    Elemtype e;//資料域 
    struct Node *next;//指標域
} Node , *LinkList;

二、操作集

初始化

void createList( LinkList *L )
{
    
*L = ( LinkList ) malloc ( sizeof(Node) ); (*L)->next = NULL; (*L)->e = 0; }

建立頭結點,頭結點儲存表長。

建立整張表

void createListHead( LinkList *L , int n )
{
    LinkList p;
    int i;
    srand( time(0) );
    //建立頭結點
    *L = ( LinkList ) malloc ( sizeof(Node) );
    (*L)->next = NULL;
    
    for
( i = 0 ; i < n ; i++ ) { p = ( LinkList ) malloc ( sizeof(Node) ); p->e = rand() % 100 + 1; p->next = (*L)->next; (*L)->next = p; } }

使用頭插法建立一張n個1-100數的隨機數表。

void createListTail( LinkList *L , int n )
{
    LinkList p,r;//p新節點指標,r尾指標 
    int i;//節點數目 
srand(time(0)); //建立頭結點 *L = ( LinkList ) malloc ( sizeof(Node) ); r = *L;//尾指標先指向頭節點 for( i = 0 ; i < n ; i++ ) { p = ( LinkList ) malloc ( sizeof(Node) ); p->e = rand() % 100 + 1; r->next = p; r = p;//指向尾部 } r->next = NULL;//最後指向空 }

使用頭插法建立一張n個1-100數的隨機數表。

讀取

int getList( LinkList L , int i, Elemtype *e ) 
{
    //計數器 
    int j = 1;
    //指向第一個節點 
    LinkList p = L->next;
    
    while( p != NULL && j < i )
    {
        p = p->next;
        j++;
    }
    
    /*第i個元素不存在*/
    if( !p || j > i )
    {
        return 0;
    }
    
    *e = p->e;
    return 1;  
}

插入操作

int insertList( LinkList *L , int i , Elemtype e )
{
    int j = 1;
    LinkList p = *L;
    
    while( p && j < i )
    {
        p = p->next;
        j++;
    }
    
    //該位置不存在,超過表長或者為負數 
    if( !p || j > i )
    {
        return 0;
    }
    
    LinkList s = ( LinkList ) malloc ( sizeof(Node) );
    s->e = e;
    s->next = p->next;
    p->next = s;
    (*L)->e+=1;
    return 1;
}

步驟見下圖,注意順序,一步錯步步錯。

刪除操作

int deleteList( LinkList *L , int i , Elemtype *e )
{
    int j = 0;
    LinkList q,p;
    
    p = *L;//頭指標賦值
    j = 1;
    
    //找到被要刪除元素的上一個元素 
    while( p->next && j < i )
    {
        p = p->next;
        j++;
    }
    
    /*第i個元素不存在*/ 
    if( !(p->next) || j > i )
    {
        return 0;
    }
    
    q = p->next;
    p->next = p->next->next;
    *e = q->e;
    free(q);
    
    return 1;
}

刪除節點的過程,看圖更容易理解

遍歷操作

void printList( LinkList L )
{
    LinkList p = L->next;
    while( p )
    {
        printf("%d ",p->e);
        p = p->next;
    }
    printf("\n列印完成");
}

清空操作

int ClearList( LinkList *L )
{
    LinkList p,q;
    p = (*L)->next;//指向第一個節點
    
    while( p!=NULL )
    {
        q = p->next;
        free(p);
        p = q;
    } 
    (*L)->next = NULL;
    return 1;
}

主函式

int main()
{
    Node *L;
    Elemtype a;
    
    createListHead(&L,10);
    printList(L);
    
    return 0;
}

紙上得來終覺淺,絕知此事要躬行

——陸游