1. 程式人生 > >連結串列建立及其相關功能

連結串列建立及其相關功能

1.編寫函式,完成在第n個節點的後增加節點的功能,n值由鍵盤輸入。(注意健壯性,要求能夠對不同的n值做出恰當的處理)。

2.編寫函式,完成在第n個節點的後刪除節點的功能,n值由鍵盤輸入。(注意健壯性,要求能夠對不同的n值做出恰當的處理)。

3.編寫函式,刪除所有資料值為奇數的節點。(注意健壯性,奇數節點可以在任意位置,頭、尾、中間,刪除了之後可能刪光了)。

4.要求每次增刪節點後可以顯示更新後的連結串列元素個數及每個節點的資訊。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define L sizeof(struct link)
int len;
struct link
{
    int data;
    struct link* next;
};
struct link *appendnode(struct link *head);       //建立連結串列,新增節點
void display(struct link *head);                 //輸出連結串列所有資訊
struct link *insertnode(struct link *head);       //插入節點
struct link *deletenode(struct link *head);       //刪除節點
struct link *deleteodd(struct link *head);         //刪除data為奇數的節點

void display(struct link* head)
{
    struct link *p=head;           //連結串列型別的指標變數為首地址
    int j=1;
    while(p!=NULL)
    {
        printf("%5d%8d\n",j,p->data);
        j++;
        p=p->next;
    }
}
int main()
{
    int x=1;
    printf("how long node do you append\n");
    scanf("%d",&len);
    struct link *head=NULL;
    head=appendnode(head);          //先自己手動建立一個連結串列
    display(head);
    while(x)                     //展示選單功能
    {
        printf("         1:insertnode!\n");   //完成在第n個節點的後增加節點的功能,n值由鍵盤輸入
        printf("         2:deletenode!\n");    //完成刪除第n個節點的功能,n值由鍵盤輸入
        printf("         3:deleteodd!\n");      //刪除data為奇數的節點
        printf("         0:finish!\n");
        printf("Please your choice!\n");
        scanf("%d",&x);
        switch(x)
        {
        case 1:
            head=insertnode(head);
            display(head);
            break;
        case 2:
            head=deletenode(head);
            display(head);
            break;
        case 3:
            head=deleteodd(head);
            display(head);
            break;
        case 0:
            exit(0);
        }
        if(head==NULL)
            break;
    }
    return 0;
}
struct link *appendnode(struct link *head)           //建立連結串列
{
    struct link *p=NULL,*pr=head;
    int data,i;
    for(i=1; i<=len; i++)
    {
        p=(struct link*)malloc(L);         //為每一個節點申請空間
        if(p==NULL)
        {
            printf("no enough memory to allocate!");
            exit(0);
        }
        if(head==NULL)
        {
            head=p;
            pr=head;
        }
        else
        {
            pr->next=p;           //把p的地址賦值給pr的下一個地址
            pr=pr->next;
        }
        printf("Input data\n");
        scanf("%d",&data);
        p->data=data;
        if(i==len)
            p->next=NULL;          //最後一個節點的下一個地址為空
    }
    return head;
};
struct link *insertnode(struct link *head)          //完成在第n個節點的後增加節點的功能,n值由鍵盤輸入
{
    int n,i,data;
    struct link *p=NULL,*pr=head,*temp=NULL;
    printf("Which node do you want to insert?(1~%d)\n",len);
    scanf("%d",&n);
    while(n<1||n>len)
    {
        printf("Please input again!\n");
        scanf("%d",&n);
    }
    p=(struct link *)malloc(L);     //為要插入的節點申請空間
    if(p==NULL)
    {
        printf("no enough memory to allocate!\n");
        exit(0);
    }
    for(i=1; i<n; i++)    //將當前pr指向第n個節點的位置
    {
        pr=pr->next;
    }
    if(n<len)           //輸入的n不是最後一個節點
    {
        p->next=pr->next;
        pr->next=p;
    }
    else               //如果輸入的n是連結串列最後一個節點,申請的空間p下一個地址指向NULL
    {
        pr->next=p;
        p->next=NULL;
    }
    printf("Input data!\n");
    scanf("%d",&data);
    p->data=data;
    len++;
    return head;
};
struct link *deletenode(struct link *head)           //完成刪除第n個節點的功能,n值由鍵盤輸入
{
    struct link *p=head,*pr=head;
    int i,n;
    printf("Which node do you want to delete?(1~%d)\n",len);
    scanf("%d",&n);
    while(n<1||n>len)
    {
        printf("Please input again!\n");
        scanf("%d",&n);
    }
    if(len==1&&n==1)       //如果連結串列只有一個節點
    {
        head=NULL;
        free(p);         //釋放當前節點的記憶體
        len--;
        printf("Linked list is completely deleted!\n");           //連結串列裡的節點都被刪除
        return head;
    }
    if(n==1)
    {
        head=p->next;   //如果n為1,頭節點就為下一個節點
        free(p);
        len--;
        return head;
    }
    for(i=1; i<n-1; i++)      //如果n不為1,pr指向第n-1個節點
    {
        pr=pr->next;
    }
    for(i=1; i<n; i++)         //如果n不為1,p指向第n個節點
    {
        p=p->next;
    }
    pr->next=p->next;         //把p的下一個地址賦值給pr的下一個地址
    free(p);
    len--;
    return head;
};
struct link *deleteodd(struct link *head)                 //刪除data為奇數的節點
{
    struct link *p=head,*pr=head,*temp=head,*text=head;
    int i,j=1,k=0;
    for(i=1; i<len; i++)           //先處理前n-1個節點
    {
        if(p->data%2==1)      //data為奇數
        {
            if(p==head)
            {
                head=p->next;    //如果是頭節點,頭節點就指向p的下一個地址
                free(p);
                p=head,pr=head;
            }
            else
            {
                pr->next=p->next;
                free(p);           //刪除data為奇數的節點
                p=pr->next;
            }
            k++;

        }
        else
        {
            j++;
            p=p->next;
        }
        if(j>2)
            pr=pr->next;

    }
    len-=k;
    temp=head,text=head;       //處理第n個節點
    for(i=1; i<len; i++)
        temp=temp->next;
    if(temp->data%2==1)
    {
        if(len==1)     //僅剩下一個節點
        {
            head=NULL;
            free(temp);
            len--;
            printf("Linked list is completely deleted!\n");    //連結串列裡的節點都被刪除
        }
        else
        {
            for(j=1; j<len-1; j++)
                text=text->next;
            text->next=NULL;
            free(temp);
            len--;
        }
    }
    return head;
};
時刻把握好pr 、p 和head 的位置,這類問題就能輕鬆解決。