線性表~單鏈表~基本操作及擴展操作

#include
#include<stdlib.h>

typedef struct node               //結點類型(名稱)
{
    int data;                     //結點的數據域
    struct node *next;            //結點的後繼指針
} linknode,*linkp;

/*單鏈表的使用~函數申明*/
linkp creatList(linkp head);      //建立單鏈表
void printfList(linkp head);      //打印鏈表
int lengthList(linkp head);       //求單鏈表長度
int searchList(linkp head);       //按序號查找表中元素
linkp insertLink(linkp head);     //插入新結點
linkp deleteLink(linkp head);     //刪除表中結點
linkp inversionLink(linkp head);  //倒置鏈表
linkp mergeLink(linkp head,linkp head2);//合併鏈表

int main()
{
    linkp head,head2,head3;


    head=(linkp)malloc(sizeof(linknode));   //malloc分配內存成功返回的爲內存的首地址
    head->next=NULL;
    head=creatList(head);           //建立單鏈表


    head2=(linkp)malloc(sizeof(linknode));
    head2->next=NULL;
    head2=creatList(head2);         //建立單鏈表


    head3=(linkp)malloc(sizeof(linknode));
    head3->next=NULL;
    head3=mergeLink(head,head2);
    printfList(head3);              //單鏈表的順序合併

    lengthList(head);               //求鏈表長度

    printfList(head);               //打印鏈表

    searchList(head);               //按序號查找報表中元素

    head=insertLink(head);          //插入新結點
    printfList(head);

    head=deleteLink(head);          //刪除表中結點
    printfList(head);

    head=inversionLink(head);       //單鏈表的倒置
    printfList(head);
}
//函數定義

/*單鏈表的基本操作*/

linkp creatList(linkp head)        //建立單鏈表
{
    int a,i=1;
    linkp p,t;
    head=(linkp)malloc(sizeof(linknode));
    t=head;
    printf("請輸入第%d個數據元素:",i);
    scanf("%d",&a);               //輸入數據元素
    while(a!=-1)
    {
        p=(linkp)malloc(sizeof(linknode));  //申請新結點
        p->data=a;
        t->next=p;
        t=p;                      //存入數據,將新結點鏈入表尾
        i++;
        printf("請輸入第%d個數據元素:",i);
        scanf("%d",&a);
    }
    t->next=NULL;                 //表尾後繼置空,防止野指針
    return head;
}

void printfList(linkp head)       //打印單鏈表
{
    linkp p=head->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

int lengthList(linkp head)        //求單鏈表長度
{
    linkp p=head->next;
    int num=0;
    while(p)
    {
        num++;
        p=p->next;
    }
    printf("單鏈表長度爲 %d\n",num);
    return num;
}

int searchList(linkp head)       //按序號查找表中元素
{
    int i,j=0;
    linkp p=head;
    printf("請輸入需要查找的元素編號:");
    while(~scanf("%d",&i))
    {
        if(i<0)
            printf("輸入有誤,請重新輸入:");
        else break;
    }
    while(p->next&&j<i)
    {
        p=p->next;
        j++;
    }
    if(j==i) printf("需要查找的元素值爲%d\n",p->data);
    else  printf("需要查找的元素不存在!!!");
}

linkp insertLink(linkp head)     //插入新結點
{
    int x,n,i=1;
    linkp p,q;
    printf("請輸入需要插入結點的位置:");
    while (~scanf("%d",&x))
    {
        if(x<1||x>lengthList(head)+1)
            printf("輸入有誤,請重新輸入:");
        else
        {
            printf("請輸入要插入的數據元素:");
            scanf("%d",&n);
            break;
        }
    }
    p=head;
    while(i!=x)
    {
        p=p->next;
        i++;
    }
    q=(linkp)malloc(sizeof(linknode));
    q->data=n;
    q->next=p->next;
    p->next=q;
    return head;
}

linkp deleteLink(linkp head)   //刪除單鏈表結點
{
    int n,i=1;
    linkp p,q;
    p=head;
    printf("請輸入需要刪除結點的位置:");
    while(~scanf("%d",&n))
    {
       if(n<1||n>lengthList(head))
       {
           printf("輸入有誤,請重新輸入:");
       }
       else break;
    }
    while(i!=n)
    {
        p=p->next;
        i++;
    }
    q=p->next;
    p->next=q->next;
    return head;
}

/*單鏈表的擴展運算*/

linkp inversionLink(linkp head)      //倒置單鏈表
{
    linkp p,q;
    p=head->next;
    head->next=NULL;
    while(p)
    {
        q=p;
        p=p->next;                   //q=p,對指針q進行操作同時也會影響到指針p
        q->next=head->next;
        head->next=q;
    }
    return head;
}

linkp mergeLink(linkp head,linkp head2)   //單鏈表的順序合併
{
    linkp p1,p2,head3;
    if(head->next->data < head2->next->data)  //找出兩個鏈表中第一個結點較小的結點,head3記錄較小結點的頭結點
    {
        head3=head;
        p1=head->next;
        p2=head2->next;
    }
    else
    {
        head3=head2;
        p2=head2->next;
        p1=head->next;
    }
    linkp r=head3;
    while(p1&&p2)                             //在兩個鏈表中遍歷比較,將值較小的結點鏈接到r結點後
    {
        if(p1->data <= p2->data)
        {
            r->next=p1;
            r=p1;
            p1=p1->next;
        }
        else
        {
            r->next=p2;
            r=p2;
            p2=p2->next;
        }
    }                                        //將p1或p2剩餘的結點鏈到r之後,完成整個合併的過程
    if(p1)
        r->next=p1;
    if(p2)
        r->next=p2;
    return head3;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章