1. 程式人生 > >C語言實現線性表的鏈式儲存結構

C語言實現線性表的鏈式儲存結構

線性表的鏈式儲存結構

特點

  • 結點除自身的資訊域外,還有表示關聯資訊的指標域。因此,鏈式儲存結構的儲存密度小、儲存空間利用率低。
  • 在邏輯上相鄰的結點在物理上不必相鄰,因此,不可以隨機存取,只能順序存取。
  • 插入和刪除操作方便靈活,不必移動結點只需修改結點中的指標域即可。

為什麼叫連結串列

為了表示每個資料元素ai與其後繼元素之間的邏輯關係,對ai來說,除了儲存其本身資訊外,還需要一個儲存直接後繼的位置資訊。我們把資料元素資訊的域叫做資料域,把儲存直接後繼位置的域稱為指標域。指標域中儲存的資訊稱為指標或者鏈。這兩部分資訊組成元素ai的儲存映像,稱為結點。

帶結點的單鏈表實現

  • S_LinkList.h檔案
#ifndef S_LinkList
#define S_LinkList
/*---------LinkList storage structure----------------*/
typedef int ElemType;
typedef struct Node
{
    ElemType data;/*data field*/
    struct Node * next;/*ptr next*/
} Node;
typedef struct Node * LinkList;/*define the LinkList*/
/*-----------------Init the LinkList------------------*/
void InitLinkList(LinkList *); /*---------------Create the LinkList------------------*/ void CreateLinkList(LinkList*); /*---------------Print the LinkList-------------------*/ void PrintLinkList(LinkList); /*---------------Clear the LinkList-------------------*/ void ClearLinkList(LinkList); /*-------------the length of the LinkList-------------*/
int LinkListLength(LinkList); int IsEmpty(LinkList); ElemType GetElem1(LinkList,int); int Modify(LinkList *,int,ElemType); int ListInsert1(LinkList*,int,ElemType); int ListDelete1(LinkList*,int,ElemType*); void Reverse(LinkList*); #endif
  • .c 檔案
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "S_LinkList.h"

/*implement*/
void InitLinkList(LinkList *lp)
{
    *lp=NULL;
    printf("-------->連結串列初始化<---------\n");
}
void CreateLinkList(LinkList *ph)
{
    LinkList p,r;
    int i,n;
    (*ph)=(LinkList)malloc(sizeof(Node));
    r=(*ph);
    printf("輸入建立連結串列的結點的個數:\n");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        p=(Node*)malloc(sizeof(Node));
        scanf("%d",&p->data);
        r->next=p;//表尾部結點指向新結點
        r=p;//將當前的新節點定義為表尾部結點,實時跟蹤
    }
    r->next=NULL;//表示當前連結串列結束
}

void PrintLinkList(LinkList ph)
{
    LinkList tmp=ph->next;
    if(tmp==NULL){
        printf("連結串列為空!");}
    else
    {
        while (tmp!=NULL)
        {
            printf("%d\t",tmp->data);
            tmp=tmp->next;
        }
        printf("\n列印完成!\n");
    }
}

void ClearLinkList(LinkList *ph)
{
    LinkList p,q;
    p=(*ph)->next;
    while (p)
    {
        q=p->next;
        free(p);
        p=q;
    }
    (*ph)->next=NULL;
}

int LinkListLength(LinkList ph)
{
    LinkList tmp=ph;
    int length=0;
    if(tmp->next=NULL)
    {
        length=0;
    }
    else
    {
        while (tmp->next->next!=NULL)
        {
            length++;
        }
        length+=1;
    }
    printf("連結串列長度%d\n", length);  
    return length;
}
int IsEmpty(LinkList ph)
{
    int status;

    if(ph->next==NULL)
    {
        status=1;
        printf("連結串列為空!\n");
    }
    else
    {
        status=0;
        printf("連結串列非空!\n");
    }
    return status;
}
ElemType GetElem1(LinkList ph,int pos)
{
    int index=0;
    LinkList tmp=ph->next;//First index nummber.
    if(pos<1)
    {
        printf("pos值不合法!\n");
        return 0;
    }
    if(tmp==NULL)
    {
        printf("連結串列為空!\n");
        return 0;
    }
    while (tmp!=NULL)
    {
        ++index;
        if(index==pos)
        {
            break;
        }
        tmp=tmp->next;
    }
    if(index<pos)
    {
        printf("超出索引範圍!");
        return 0;
    }
    return tmp->data;
}
int Modify(LinkList *ph,int pos,ElemType e)
{
    LinkList tmp;
    int index;
    tmp=(*ph)->next;
    if(pos<1)
    {
        printf("這個位置不合法!\n");
        return 0;
    }
    if(tmp==NULL)
    {
        printf("連結串列為空!\n");
        return 0;
    }
    while(tmp!=NULL)
    {
        ++index;
        if(index==pos)
        {
            break;
        }
        tmp=tmp->next;
    }
    if(index<pos)
    {
        printf("這個位置不合法!\n");
        return 0;
    }

    tmp->data=e;
    printf("Modify後第%個數修改為%d!\n",index,tmp->data);
    return 1;
}
int ListInsert1(LinkList *ph,int pos,ElemType e)
{
    int index;
    LinkList p,s;//p signed as HeadLink and s is a new Link that will be added.
    p=(*ph);
    index=1;
    while (p&&index<pos)
    {
        p=p->next;
        index++;
    }
    if(!p||index>pos)
    {
        return 0;
    }
    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    p->next=s;
    printf("成功插入元素%d與%位置!\n",s->data,index);
    return 1;
}
int ListDelete1(LinkList *ph,int pos,ElemType *e)
{
    int index;
    LinkList p,q;
    p=(*ph);
    index=1;
    while (p->next&&index<pos)
    {
        p=p->next;
        index++;
    }
    if(!(p->next)||index>pos)
    {
        return 0;
    }
    q=p->next;
    p->next=q->next;
    *e=q->data;
    free(q);
    printf("刪除的第%d個結點%d成功!\n",pos,*e);
    return 1;
}
void Reverse(LinkList *ph)
{
    //assign it has the head node.
    LinkList q,current,p;
    q=(*ph);
    current=(*ph)->next;
    while (current->next!=NULL)
    {
        p=current->next;
        current->next=p->next;
        p->next=q->next;
        q->next=p;
    }
    printf("逆序連結串列完成!\n");
}
  • 除錯結果
#include <stdlib.h>
#include <stdio.h>
#include "S_LinkList.h"

int main()
{
    LinkList p;
    InitLinkList(&p);
    CreateLinkList(&p);
    PrintLinkList(p);
    system("pause");
    return 0;
}

如果有什麼可以交流的歡迎大家留言一起探討。