數據結構線性表鏈表的C語言實現


                                                                                      數據結構線性表鏈表的C語言實現

     說明:線性表是一種最簡單的線性結構,也是最基本的一種線性結構,所以它不僅是學習中的重點,也是應用開發非常常用的一種數據結構。它可以分為順序表鏈表。它的主要操作是數據元素的插入刪除,以及排序等。接下來,本篇文章將對線性鏈表的基本操作和運用進行詳細的說明(包含在源代碼的注釋中),並給予可運行的程序源代碼。

     線性表鏈表不同於順序表,它是一種鏈式的線性表,和順序表的類似數組的存儲特點不同,它是一個個獨立的存儲單元,中間用指針鏈接,類似一條鏈子,所以叫鏈表。因為同屬線性表所以它的基本操作與順序表是一致的,所以基本操作函數名相同但是具體實現方式不同,順序表的優點在於它可以隨機存儲數據元素,但在刪除和插入操作時需要移動大量元素。而鏈表則相反,它無法做到隨機存取,但在進行刪除和插入操作時非常方便,僅需要修改下指針並釋放被刪除元素的存儲空間而已。

     程序分析:由於抱着是程序執行起來時操作盡量簡單化,使人一看就能明白,所以本程序是用了不少的提示性語句。主函數的結構是while循環和switch函數相結合的方法,使每種能夠用到的基本操作盡量明白的顯示在主顯示函數中,這樣能使每種基本操作的作用效果更加突出明了。這樣不僅能使程序的模塊化盡量明顯,也可以讓源代碼的可讀性增強。而且程序運用了CLS清屏函數,可以使每一次操作的輸入輸出結果更加清晰。

源代碼:

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

#define   OK      1

#define  ERROW   -1

#define OVERFLOW -2

#define  LEN  sizeof(struct Lnode)

#define  LN  LNode * 

typedef  int  Status;

typedef  int  ElemType;

 

/*鏈表的結點的數據結構 */

typedef struct Lnode

{

  ElemType num;      //為求簡便數據域僅置一項 

  struct Lnode *next;

}LNode,*LinkList;     // *LinkList  L 定義鏈表頭指針

 

/*鏈表的初始構建函數*/ 

Status InitList(LinkList &L)

{

   L=(LN)malloc(LEN);

   if(L==0)

   exit(OVERFLOW);

    L->next=NULL;

    return OK;

 } 

 

/*鏈表的清空涵數*/ 

void  ClearList(LinkList &L)

{   

    LinkList p;

   while(L->next)

 {

    p=L->next;

    L->next=p->next;

   free(p);

}

// 最終效果是只保留頭節點

}

     /*銷毀函數*/ 

void DestoryList(LinkList &L)

{

     ClearList(L);

     free(L); //釋放頭節點空間 

     L=NULL;//鏈表的變量歸於初始值,便於識別和處理

}

 

  /*取表長函數*/

Status GetLength(LinkList L)

{

    int n;

    n=0;

    if(L==NULL)//未經初始構建函數構建或已經徹底銷毀 

    return n;

   while(L->next)

  {

   L=L->next;

   n++;

 }

return n;

}

 

/*判斷表的空否的函數 */ 

Status IsEmpty(LinkList L)

{

    if(L->next==NULL)

     return OK;

    else

   return ERROW;

}

 

/*定位取值函數*/

Status GetElem(LinkList L,int i,ElemType &e)

{

     int j=1;

     LinkList p;

    p=L->next;

    while(p&&j<i)

  {

       p=p->next;

      j++;

    }

  if(p==NULL||j>i)  //所給位置序號超出表長 

  {

    printf("序號輸入錯誤!\n\n");

   return ERROW;

  }

  e=p->num;

return OK; 

}

 

/*查找定位函數*/ 

Status LocateElem(LinkList L,int &i,ElemType e)

{

      i=1;

     LinkList p;

     p=L->next;

  while(p&&p->num!=e)

 {

    p=p->next;

    i++; 

}

if(p!=NULL)

 return OK;

else

 return ERROW; 

}

 

 /*創建一個鏈表*/

 void ScanList(LinkList &L)

{

     int i;

    LinkList p,p0;

    if(L==NULL)

    InitList(L);

    p0=L;

   printf("請輸入鏈表長度\n");

   scanf("%d",&i);

   printf("\n請輸入%d個數\n",i);

    for(;i>0;i--) 

  {

  p=(LN)malloc(LEN);

  p->next=NULL;

  scanf("%d",&p->num);

  p0->next=p;

  p0=p;

 }

}

 

/*輸出表中所有數據元素*/

void PrintList(LinkList L)

{

    LinkList p0;

    p0=L->next;

    printf("\n");

    while(p0!=NULL)

   {

       printf("%d  ",p0->num);

       p0=p0->next;

    }

printf("\n");

}

 

 /*數據元素插入函數*/

Status ListInsert(LinkList &L,int i,ElemType e)

{

   int j=0;

   LinkList p,p0;

   p=L;

  while(p&&j<i-1)

{

    p=p->next;

    j++; 

  if(p==NULL||j>i)

 {

    return ERROW;

}

  p0=(LN)malloc(LEN);

  p0->num=e;

  p0->next=p->next;

  p->next=p0;

  return OK;

}

 

/*定位刪除函數*/ 

Status ListDelete_1(LinkList &L,int i)

{

    int j=0;

   LinkList p,p0;

   p=L;

  while(p&&j<i-1)

{

     p=p->next;

     j++; 

  if(p==NULL||j>i)

{

     return ERROW;

}

     p0=p->next;

     p->next=p0->next; 

     free(p0);

    return OK;

}

 

/*非遞減冒泡排序函數*/ 

int maopao(LinkList &L)

{ 

     int i,j,t,n;

     LinkList p,p0;

     p0=L;

     n=GetLength(L);

   for(j=1;j<=n-1;j++)

{

      p0=p0->next;

      p=p0;

   for(i=1;i<=n-j;i++)

   {

      if(p->num>p->next->num)

     {

         t=p->num;

         p->num=p->next->num;

         p->next->num=t;

     }

    p=p->next;

 }

}

return OK;

}

 

/*主提示函數*/ 

void printlin()

{

   printf("\n");

   printf("\t\t\t線性鏈表基本操作學習系統\n");

   printf("\t\t\t      ***主菜單***\n\n"); 

   printf("\t\t\t    *1 創建一個鏈表表\n");

   printf("\t\t\t    *2 定位輸出一個數據元素\n");

   printf("\t\t\t    *3 輸出鏈表中所有元素\n");

   printf("\t\t\t    *4 定位插入一個數據元素\n");

   printf("\t\t\t    *5 定位刪除一個數據元素\n");

   printf("\t\t\t    *6 定值刪除一個數據元素\n"); 

   printf("\t\t\t    *7 清空鏈表\n");

   printf("\t\t\t    *8 銷毀鏈表\n");

   printf("\t\t\t    *9 對表內數據元素進行非遞減排序\n"); 

   printf("\t\t\t    *0 結束程序\n");

}

 

  int main()

{

          int i,j,k;

          LinkList L;

          L=NULL;

         printf("編寫此程序目的是自我學習線性表鏈表\n");

         printlin();

   while(1)

  {

        int t;

        scanf("%d",&t);

      if(t!=0) 

         if(t==1||GetLength(L)!=0)

        {

              switch(t)

             {

                   case 1:   if(GetLength(L)!=0)

                                {

                                    printf("鏈表已存在,是銷毀並重新創建鏈表?\n");

                                    printf("*1 是   *2 \n");

                                    scanf("%d",&i);

                                      if(i==1)

                                     {

                                           DestoryList(L); 

                                           ScanList(L);

                                     }          

                                  }

                                else

                                  ScanList(L);

                                  break;

                   case 2:   {

                                    k=GetLength(L);

                                    printf("請輸入數據位置\n");

                                    scanf("%d",&i);

                                    if(i<1||i>k)

                                        printf("輸入位置錯誤\n");

                                    else 

                                     {

                                           GetElem(L,i,j);

                                            printf("%d個數為%d\n",i,j);

                                       }

                                       break;

                                  }

                   case 3:    PrintList(L);break;                  

                   case 4:    {

                                       printf("輸入要插入的位置\n");

                                       scanf("%d",&i);

                                       printf("請輸入要插入的數據\n");

                                       scanf("%d",&j);

                                       k=ListInsert(L,i,j); 

                                      if(k==-1)

                                        printf("插入位置不合法,插入數據操作失敗!\n\n");

                                      else 

                                        printf("插入數據成功\n\n");

                                     break;

                                 }

                   case 5:   {

                                      printf("請輸入要刪除數據位置\n");

                                      scanf("%d",&i);

                                       k=ListDelete_1(L,i);

                                      if(k==-1)

                                            printf("輸入位置錯誤,刪除操作失敗!\n\n");

                                     else

                                         printf("刪除成功!\n\n");

                                     break;

                                 }

                 case 6:   {

                                   printf("請輸入需要刪除的元素:\n");

                                   scanf("%d",&j);

                                   k=LocateElem(L,i,j);

                                   if(k==-1)

                                     printf("未找到該元素,刪除操作失敗!\n\n");

                                 else

                                  {

                                    ListDelete_1(L,i);

                                    printf("刪除成功!\n\n");

                                   }

                                     break;

                              }  

                case 7:  {

                                  ClearList(L);

                                  printf("清空完畢,返回主菜單\n\n");

                                  break;

                              }

              case 8:   {

                                  DestoryList(L);

                                  printf("銷毀成功,返回主菜單\n\n");

                                   break;

                             }

             case 9:    {

                               maopao(L);

                               printf("已成功排序,返回主菜單\n\n");

                               break;

                             }  

            case 0:    break;

           default:   {

                            printf("輸入有誤,可以重新選擇,退出按0\n\n");          

                           }

             }

         } 

        else

           printf("鏈表未創建或已清空或銷毀,請先創建鏈表\n\n");

     system("pause");

    system("CLS");

     printlin();

    if(t==0)

       break;

  } 

 return 0;

}

 

程序運行效果圖 (部分):

 

                         

                                                                           圖 1

 

 

                         

                                                                          圖2

 

 

                          

                                                                       圖3

 

 

                           

                                                                         圖4

 

 

 

 

結束語:紙上得來終覺淺,絕知此事要躬行!


免責聲明!

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



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