【C語言】數據結構C語言版 實驗3 帶頭結點的單鏈表


slnklist.h

#include <stdio.h>
#include <stdlib.h>
/**************************************/
/* 鏈表實現的頭文件,文件名slnklist.h */
/**************************************/
 typedef int datatype;
 typedef struct link_node{
   datatype info;
   struct link_node *next;
 }node;
typedef node *linklist;
/******************************************/
/*函數名稱:creatbystack()                      */
/*函數功能:頭插法建立帶頭結點的單鏈表    */
/******************************************/
linklist creatbystack()
{
    linklist  head,s;
    datatype x;
    head=(linklist)malloc(sizeof(node));
    head->next=NULL;
    printf("請輸入整數序列(空格分開,以0結束):\n");
    scanf("%d",&x);
    while (x!=0)
    {
        s=(linklist)malloc(sizeof(node));
        s->info=x;
        s->next=head->next;
        head->next=s;
        scanf("%d",&x);
    }
    return head;
}
/***************************************/
/*函數名稱:creatbyqueue()                */
/*函數功能:尾插法建立帶頭結點的單鏈表 */
/***************************************/
linklist creatbyqueue()
{
    linklist head,r,s;
    datatype x;
    head=r=(linklist)malloc(sizeof(node));
    head->next=NULL;
    printf("請輸入整數序列(空格分開,以0結束):\n");
    scanf("%d",&x);
    while (x!=0)
    {
         s=(linklist)malloc(sizeof(node));
         s->info=x;
         r->next=s; //把新元素放到當前元素后面 
         r=s;    //把當前指針指向新元素 
         scanf("%d",&x);
   }
    r->next=NULL;
    return head;
}
/**********************************/
/*函數名稱:print()                      */
/*函數功能:輸出帶頭結點的單鏈表      */
/**********************************/
void print(linklist head)
{
    linklist p;
    int i=0;
    p=head->next;
    printf("List is:\n");
    while(p)
    {
        printf("%7d",p->info);
        i++;
        if (i%10==0)    printf("\n");
        p=p->next;
    }
    printf("\n");
}
/******************************************/
/*函數名稱:creatLink()                   */
/*函數功能:從文件中讀入n個數據構成單鏈表 */
/******************************************/
linklist creatLink(char *f, int n)
{
    FILE *fp;
    int i;
    linklist s,head,r;
    head=r=(linklist)malloc(sizeof(node));
    head->next=NULL;
    fp=fopen(f,"r");
    if (fp==NULL)
        return head;
    else
    {
         for (i=0;i<n;i++)
            {
                s=(linklist)malloc(sizeof(node));
                fscanf(fp,"%d",&(s->info));
                r->next=s;
                r=s;
            }
        r->next=NULL;
        fclose(fp);
        return head;
    }
}
/*
    函數名稱:writetofile
    函數功能:將鏈表內容存入文件f
*/
void writetofile(linklist head, char *f)
{
    FILE *fp;
    linklist p;
    int i=0;
    fp=fopen(f,"w");
    if (fp!=NULL)
    {
        p=head->next;
        fprintf(fp,"%s","List is:\n");
        while(p)
        {
            fprintf(fp,"%7d",p->info);
            i++;
            if (i%10==0)    fprintf(fp,"%c",'\n');
            p=p->next;
        }
        fprintf(fp,"%c",'\n');
        fclose(fp);
    }
    else    printf("創建文件失敗!");
}
/**********************************/
/*函數名稱:delList()                  */
/*函數功能:釋放帶頭結點的單鏈表      */
/**********************************/
void delList(linklist head)
{ linklist p=head;
  while (p)
  { head=p->next;
    free(p);
    p=head;
  }
}

源文件

/*編寫函數void delx(linklist head, datatype x),刪除帶頭結點單鏈表head中第一個值為x 的結點。
並構造測試用例進行測試。
*/
/**********************************/
/*文件名稱:lab3_01.c                 */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist delx(linklist head,datatype x)
{
    linklist p,pre=head; //別忘了pre=head 
    p = head->next;
    while(p->info!=x)
    {
        pre = p;
        p = p->next;
    }
    if(p)
    {
        pre->next = p->next;
        free(p);
    }
    return head;
}
int main()
{   datatype x;
    linklist head;
    head=creatbyqueue();        /*尾插入法建立帶頭結點的單鏈表*/
    print(head);
    printf("請輸入要刪除的值:");
    scanf("%d",&x);
    head=delx(head,x);            /*刪除單鏈表的第一個值為x的結點*/
    print(head);
    delList(head);                /*釋放單鏈表空間*/
    return 0;
}
/**********************************/
/*文件名稱:lab3_02.c                 */
/**********************************/
/*
假設線性表(a1,a2,a3,…an)采用帶頭結點的單鏈表存儲,請設計算法函數linklist reverse(linklist  head),
將帶頭結點的單鏈表head就地倒置,使表變成(an,an-1,…a3.a2,a1)。並構造測試用例進行測試。
*/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist reverse(linklist head)
{
    //不帶頭節點是head,帶頭節點是head->next 
    linklist p,q;
    p = head->next;
    head->next = NULL;
    while(p)
    {
        q = p->next;
        p->next = head->next;
        head->next = p;
        p = q;
    }
    return head;
}
int main()
{   datatype x;
    linklist head;
    head=creatbystack();            /*頭插入法建立帶頭結點的單鏈表*/
    print(head);                    /*輸出原鏈表*/
    head= reverse(head);            /*倒置單鏈表*/
    print(head);                    /*輸出倒置后的鏈表*/
    delList(head);
    return 0;
}
/*
假設帶頭結點的單鏈表head是升序排列的,設計算法函數linklist insert(linklist head,datatype x),
將值為x的結點插入到鏈表head中,並保持鏈表有序性。
分別構造插入到表頭、表中和表尾三種情況的測試用例進行測試。
*/
/**********************************/
/*文件名稱:lab3_03.c                 */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist insert(linklist head ,datatype x)
{
    //要插入的數據s,位於pre和 p之間 
    linklist pre,p,s;
    s = (linklist)malloc(sizeof(node));
    s->info = x;
    p = head->next;
    pre = head;
    while(p&&p->info<x)
    {
        pre = p;
        p = p->next;
    }
    pre->next = s;
    s->next = p;
    return head;
}
int main()
{   datatype x;
    linklist head;
    printf("輸入一組升序排列的整數:\n");
    head=creatbyqueue();                /*尾插入法建立帶頭結點的單鏈表*/
    print(head);
    printf("請輸入要插入的值:");
    scanf("%d",&x);
    head=insert(head,x);                /*將輸入的值插入到帶頭結點的單鏈表適當位置*/
    print(head);
    delList(head);
    return 0;
}
 

 

/*
編寫算法函數linklist delallx(linklist head, int x),刪除帶頭結點單鏈表head中所有值為x的結點。
*/
/**********************************/
/*文件名稱:lab3_04.c                 */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist delallx(linklist head,int x)
{
    //不帶頭節點是head,帶頭節點是head->next 
    linklist p,t;
    while(head->next)//如果要刪除的是第一個 
    {
        if(head->next->info==x)//如果第一個數=x 
        {
            p=head->next;//刪除操作 
            head->next=head->next->next;
            free(p);//回收p 
        } else {
            break;
        }
    }
    if(head->next)//如果刪除的不是第一個 
    {
        p=head->next;
        while(p->next)
        {
            if(p->next->info==x)
            {
                t=p->next;
                p->next=p->next->next;
                free(t);
            } else {
                p=p->next;
            }
        }
    }
    return head;
}
int main()
{   datatype x;
    linklist head;
    head=creatbyqueue();                /*尾插入法建立帶頭結點的單鏈表*/
    print(head);
    printf("請輸入要刪除的值:");
    scanf("%d",&x);
    head=delallx(head,x);
    print(head);
    delList(head);
    return 0;
}
/*
已知線性表存儲在帶頭結點的單鏈表head中,請設計算法函數void sort(linklist head),將head中的結點按結點值升序排列。
*/
/**********************************/
/*文件名稱:lab3_05.c                 */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
void  sort(linklist head)
{
     int temp; //temp是int類型,notice 
     linklist p,pre;
     pre=p=head->next;
     while(pre) //pre是前面那個數,p是后面那個數 
     {
         p=pre;//notice,p是從pre后面數里走 
         while(p)
         {
             if(pre->info>p->info) //交換 
             {
                 temp=p->info;
                 p->info=pre->info;
                 pre->info=temp;
             }
             p=p->next;
         }
         pre=pre->next;
     }
     return head;
}
int main()
{        linklist head;
         head=creatbyqueue();           /*尾插法建立帶頭結點的單鏈表*/
         print(head);                    /*輸出單鏈表head*/
         sort(head);                     /*排序*/
         print(head);
         delList(head);
         return 0;
}
/*
已知兩個帶頭結點的單鏈表L1和L2中的結點值均已按升序排序,設計算法函數
linklist mergeAscend (linklist L1,linklist L2)將L1和L2合並成一個升序的
帶頭結單鏈表作為函數的返回結果;
設計算法函數linklist mergeDescend (linklist L1,linklist L2)
將L1和L2合並成一個降序的帶頭結單鏈表作為函數的返回結果;
並設計main()函數進行測試。
*/
/**********************************/
/*文件名稱:lab3_06.c                 */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist mergeAscend(linklist L1,linklist L2)//升序 
{
    linklist head,x,y,p;
    head=(linklist)malloc(sizeof(node));
    head->next=NULL;
    p=head;
    x=L1->next;
    y=L2->next;
    while(x&&y)
    {
        //當比到最好一個元素的時候,會出現x->next=NULL或者是y->next=NULL
        if(x->info<=y->info)//L1里的數<L2的數 
        {
            //這兩句是尾插法的核心 
            p->next=x; //把新元素插到當前元素后面去 
            p=x;  //吧當前指針指向新元素 
            x=x->next;
        }
        else
        {
            //這兩句是尾插法的核心 
            p->next=y; //把新元素插到當前元素后面去 
            p=y;  //吧當前指針指向新元素 
            y=y->next;
        }
    }
    p->next=x?x:y; //把最后一個數加進去 
    return head;
}
linklist mergeDescend(linklist L1,linklist L2)//降序 
{
}
int main()
{       linklist h1,h2,h3;
         h1=creatbyqueue();     /*尾插法建立單鏈表,請輸入升序序列*/
         h2=creatbyqueue();
         print(h1);
         print(h2);
         //升序合並請調用 
         h3=mergeAscend(h1,h2);
         //降序合並請調用
//         h3=mergeDescend(h1,h2); 
         print(h3);
         delList(h3);
         return 0;
}
/*
/*
設計一個算法linklist interSection(linklist L1,linklist L2),
求兩個單鏈表表示的集合L1和L2的交集,並將結果用一個新的帶頭
結點的單鏈表保存並返回表頭地址。
*/
/**********************************/
/*文件名稱:lab3_07.c                 */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist   interSection(linklist L1, linklist L2)
{
    linklist head,p,s,x,y; //s是臨時存儲的結點 
    head=(linklist)malloc(sizeof(node));
    head->next=NULL;
    p = head;
    x = L1->next;
    y = L2->next;
    while(x)
    {
        while(y)
        {
            if(x->info==y->info)
            {
                s = (linklist)malloc(sizeof(node));
                s->info = x->info;
                p->next = s;  //這兩句不能互換,因為是添加數據 
                p = s;
                break; //notice,不可省略 ,跳出本層循環 ,不執行y=y->next 
            }
            y = y->next;
        }
        x = x->next;
    }
    p->next = NULL;
    return head;
}
int main()
{
 linklist h1,h2,h3;
 h1=creatbyqueue();           /*尾插法建立單鏈表,輸入時請勿輸入重復數據*/
 h2=creatbyqueue();
 print(h1);                   /*輸出單鏈表h1*/
 print(h2);
 h3=interSection(h1,h2);      /* 求h1和h2的交集*/
 print(h3);
 delList(h1);
 delList(h2);
 delList(h3);
 return 0;
}
/*
請編寫一個算法函數void partion(linklist head),
將帶頭結點的單鏈表head中的所有值為奇數的結點調整
到鏈表的前面,所有值為偶數的結點調整到鏈表的后面。
*/
/**********************************/
/*文件名稱:lab3_08.c             */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
void partion(linklist head)
{
    linklist p,s,pre;
    pre=head;
    p=head->next;
    while(p)
    {
        if(p->info%2==0) //偶數 
        {
            pre=p;
            p=p->next;
        }
        else
        {
            s=p;
            pre->next=p->next;
            p=pre->next;
            s->next=NULL;
            s->next=head->next;
            head->next=s;
        }
    }
}
int main()
{        linklist head;
         head=creatbyqueue();           /*尾插法建立帶頭結點的單鏈表*/
         print(head);                   /*輸出單鏈表head*/
         partion(head);
         print(head);
         delList(head);
         return 0;
}
/*
編寫一個程序,用盡可能快的方法返回帶頭結點單鏈表中倒數第k個結點的地址,如果不存在,則返回NULL。
*/
/**********************************/
/*文件名稱:lab3_09.c             */
/**********************************/
#include "slnklist.h"
/*請將本函數補充完整,並進行測試*/
linklist   search(linklist head,int k)
{
    linklist p = head->next,x;
    int count = 0,i;
    x = p;
    while(x) //求鏈表長度 
    {
        count++;
        x=x->next;
    }        //獲得倒數第k的值 
    for(i=0;i<count-k;i++)
    {
        p = p->next;
    }
    return p;
}
int main()
{
     int k;
     linklist head,p;
     head=creatbyqueue();        /*尾插法建立帶頭結點的單鏈表*/
     print(head);                  /*輸出單鏈表head*/
     printf("k=");
     scanf("%d",&k);
     p=search(head,k);
     if (p) printf("%d\n",p->info);
     else
         printf("Not Found!\n");
     delList(head);
     return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM