鏈表基本操作與排序(c語言)


本設計程序用C編寫,完成單鏈表的生成,任意位置的插入、刪除,以及確定某一元素在單鏈表中的位置。實現三種排序算法-冒泡排序、快速排序、合並排序。產生四個長度為100,1000,10000,50000的隨機數數組,分別用這三種排序算法對每個數組進行排序,並記錄每種算法在排序所花費的計算機時間,並進行對比分析

 

① 輸入的形式和輸入值的范圍:插入元素時需要輸入插入的位置和元素的值;刪除元素時輸入刪除元素的位置;查找操作時需要輸入元素的值。在所有輸入中,元素的值都是整數。
② 輸出的形式:在所有三種操作中都顯示操作是否正確以及操作后單鏈表的內容。其中刪除操作后顯示刪除的元素的值,查找操作后顯示要查找元素的位置。
③ 程序所能達到的功能:完成單鏈表的生成(通過插入操作)、插入、刪除、查找操作。

1.定義單鏈表結構

typedef struct Node
{
    Item data;
    struct Node *next;
}Node,*ListNode;

2.初始化單鏈表

ListNode InitLinkList(ListNode *List)
{
*List = (ListNode)malloc(sizeof(struct Node)); 
(*List)->next = NULL;

3.創建隨機數的單鏈表

ListNode CreatListTail(int len)//len為單鏈表長度
{
    int i;
    ListNode p;
    srand(time(0));//啟動隨機種子數
    ListNode List = (ListNode)malloc(sizeof(struct Node));

    ListNode Tail = List;
    for(i = 0; i < len; i ++)
    {
        p = (ListNode)malloc(sizeof(struct Node));
        p->data = rand() % len + 1;//產生隨機數 
        Tail->next = p;
        Tail  = p;
    }
    Tail->next = NULL;
    return List;
}

4.打印單鏈表

void dispLinkList( ListNode List)
{
int i=0;
    while(List != NULL)
    {
        printf("%d ",List->data);
        List = List->next;
        i++;
    }
    printf("\n");
    printf("總共%d個節點",i);
}

5.單鏈表的插入操作

void InsLinkList(ListNode List,int i,int e) //插入給i位置的元素為e 
{
Node *pre,*s;
int k;
pre = List;
k=0;
while(pre !=NULL && k < i-1)
{
pre = pre->next;
k=k+1;
}
if(pre == NULL)
{
    printf("插入位置不合理");
}    
s=(ListNode)malloc(sizeof(struct Node));
s->data=e;
s->next=pre->next;
pre->next=s;
}

6.刪除單鏈表的節點i

void DelLinkList(ListNode List,int i)//刪除i位置元素,並將刪除的元素保存到*e中  
{
Node *pre,*r;
int k;
pre = List;
k=0;
while(pre !=NULL && k < i-1)
{
pre = pre->next;
k=k+1;
}
if(pre->next == NULL)
{
    printf("刪除節點不合理");

    }   
r=pre->next;
pre->next=r->next;
//*e = r->data;//並將刪除的元素保存到*e中   
free(r);
}

7.查找元素的位置

int LocLinkList(ListNode List,int e)//查找值為e的節點位置 
{
Node *p ;
int i=1;
p = List->next;
while(p != NULL)
{
    if(p->data != e)
    {
p = p->next;
    i++;}
    else break;
}
 return i;

8.對單鏈表進行歸並排序

void Split_List(ListNode List, ListNode *List_A, ListNode *List_B)
{
    ListNode fast_list;
    ListNode low_list;

    if(List == NULL || List->next == NULL)
    {
        *List_A = List;
        *List_B = NULL;
    }

    else
    {
        low_list  = List;
        fast_list = List->next;

        while(fast_list != NULL)
        {
            fast_list = fast_list->next;
            if(fast_list != NULL)
            {
                low_list  = low_list->next;
                fast_list = fast_list->next;
            }
        }

        *List_A = List;
        *List_B = low_list->next;
        low_list->next = NULL;
    }
}

ListNode Merge_List(ListNode List_A, ListNode List_B)
{
    ListNode List_Result = NULL;
    if(List_A == NULL)
        return List_B;
    if(List_B == NULL)
        return List_A;

    if(List_A->data <= List_B->data)
    {
        List_Result = List_A;
        List_A = List_A->next;
    }

    else
    {
        List_Result = List_B;
        List_B = List_B->next;
    }

    List_Result->next = Merge_List(List_A,List_B);

    return List_Result;
}


void Mergesort(ListNode *List)
{
    ListNode Head = *List;
    ListNode List_A;
    ListNode List_B;

    if(Head == NULL || Head->next == NULL)
        return;

    Split_List(Head, &List_A, &List_B);

    Mergesort(&List_A);
    Mergesort(&List_B);

    *List = Merge_List(List_A,List_B);
}

9.對單鏈表進行冒泡排序

void BubbleSort(ListNode List)
{
    Node * p, * q, * tail;

    tail = NULL;

    while((List->next->next) != tail)
    {
        p = List;
        q = List->next;
        while(q->next != tail)
        {
            if((q->data) > (q->next->data))
            {
                p->next = q->next;
                q->next = q->next->next;
                p->next->next = q;
                q = p->next;
            }
            q = q->next;
            p = p->next;
        }
        tail = q;
    }
}

10.對單鏈表進行快速排序

void swap(int &a, int &b) //引用類型方式
{
    int temp; //輔助變量
    temp = a;
    a = b;
    b = temp;   
}
void quickSort(Node* start, Node* end=NULL)
{
    if (start == NULL || start == end) return;

    Node* p1 = start;
    Node* p2 = start->next; 

    while (p2 != end) {
        if (p2->data < start->data) {
            p1 = p1->next;
            swap(p1->data, p2->data);
        }
        p2 = p2->next;
    }
    swap(p1->data, start->data);

    quickSort(start, p1);
    quickSort(p1->next, end);
}



位置下標從0開始

 

主函數:

 
int main()
{

   clock_t start, finish;;//起始 結束時間 
    double duration;//總計時間 
    ListNode Head;
    ListNode List;
printf("\n\n\n");
  printf("-------------操作選項-----------\n");
  printf("1:返回菜單 \n");
  printf("2:退出程序 \n");
  printf("3:初試化,產生隨機數 \n");
  printf("4:打印單鏈表 \n");
  printf("5:插入元素 \n");
  printf("6:刪除j位置的元素 \n");
  printf("7:查找值為k的節點位置 \n");
  printf("8:對鏈表進行冒泡排序 \n");
  printf("9:對鏈表進行快速排序 \n");
  printf("10:對鏈表進行合並排序 \n");
  printf("--------------------------------\n");
 int x,n,i,e,k,j;
 while (1)
 {  
  printf("按數字鍵選擇要執行的操作: ");
  scanf("%d",&x);
  printf("\n");

  //輸入2跳出循環,退出程序
  if(x==2)
      break;

  switch(x)
  {
  case 1:  break;   //輸入1,跳出switch語句,進入下一次循環
  case 3:  {
printf("請輸入數字n(隨機產生n個數):");
scanf("%d",&n);
  Head=CreatListTail(n);
  List = Head -> next;
   break;   
   }
   case 4:{
       dispLinkList(List);
    break;
   } 
    case 5:{
       printf("插入給i位置的元素為e \n");
       printf("請輸入i和e(中間用空格隔開)\n"); 
       scanf("%d %d",&i,&e);
       InsLinkList(List,i,e);
       break;
   } 
      case 6:{
    printf("刪除j位置的元素 \n");
    scanf("%d",&j);
       DelLinkList(List,j);
    break;
   } 
     case 7:{
    printf("查找值為k的節點位置  \n");
    printf("請輸入k\n"); 
    scanf("%d",&k);
       //LocLinkList(List,k);
       printf("%d",LocLinkList(List,k)) ;
    break;
   } 
   case 8:{
    printf("對鏈表進行冒泡排序  \n");

   start = clock();
   BubbleSort(List);
   finish = clock(); 
   duration = (double)(finish - start) / CLOCKS_PER_SEC;
   printf( "時間為 %f seconds\n", duration );
    break;
   } 
    case 9:{
    printf("對鏈表進行快速排序  \n");
    start = clock();
    quickSort(List);
    finish = clock(); 
    duration = (double)(finish - start) / CLOCKS_PER_SEC;
    printf( "時間為 %f seconds\n", duration );
    break;
   }    
   case 10:{
    printf("對鏈表進行合並排序  \n");

       start = clock();
    Mergesort(&List);

   finish = clock(); 
  duration = (double)(finish - start) / CLOCKS_PER_SEC;
   printf("時間為 %f seconds\n", duration );

    break;
   } 

  default:  //數字輸入錯誤,跳出siwtch語句,進入下一次循環
      printf("輸入的數字不正確\n");
      break;
  }
 }
 return 0;}


項目地址:https://github.com/plusyou13/c


免責聲明!

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



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