冒泡排序在单向链表中的一种体现

(1)断开

(2)插入

(3)下一步或者回退

方法一(自动回退):

//数据冒泡数据插入
void insert_sort_val(node *head)
{
    //排序部分
    node* p = head->next;
    int len = 0;
    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    int i, j;
    node* temp = head;
    node* log = head->next;
    node* log_s = head;



    for (i = 0; i < len - 1; i++)
    {
      log = head->next;
      log_s = head;
      for (j = 0; j < len - 1 - i; j++)
      {

            if (log->data > log->next->data )
            {
                  //记录位置
                  temp = log->next;

                  //断开节点
                  log_s->next = log->next;
                  log->next = temp->next;
                  temp->next = log;
                  
                  //回退
                  log = log_s->next;
                 
                
            }

            log = log->next;
            log_s = log_s->next;

      }


    }


}

方法一(修改瑕疵):

void insert_sort_val_set(node *head)
{
      if (head == NULL || head->next == NULL)
      {
            return; // 空链表或只有一个节点,无需排序
      }

      int len = 0;
      node *p = head->next;
      while (p != NULL)
      {
            len++;
            p = p->next;
      }

      for (int i = 0; i < len - 1; i++)
      {
            node *log_s = head;     // log_s 是当前节点的前驱节点
            node *log = head->next; // log 是当前节点

            for (int j = 0; j < len - 1 - i; j++)
            {
                  if (log->data > log->next->data)
                  {
                        // 交换 log 和 log->next 两个节点
                        node *temp = log->next; // temp 是 log 的下一个节点

                        // 调整指针
                        log_s->next = temp;     // log_s 的下一个节点指向 temp
                        log->next = temp->next; // log 的下一个节点指向 temp 的下一个节点
                        temp->next = log;       // temp 的下一个节点指向 log

                        // 更新 log,因为 log 和 temp 已经交换
                        log = temp;
                  }

                  // 移动到下一个节点
                  log_s = log_s->next;
                  log = log->next;
            }
      }
}

方法二(if-else规避):

//数据冒泡数据插入
void insert_sort_val(node *head)
{
    //排序部分
    node* p = head->next;
    int len = 0;
    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    int i, j;
    node* temp = head;
    node* log = head->next;
    node* log_s = head;



    for (i = 0; i < len - 1; i++)
    {
      log = head->next;
      log_s = head;
      for (j = 0; j < len - 1 - i; j++)
      {
            if (log->data > log->next->data )
            {
                  temp = log->next;
                  log_s->next = log->next;
                  log->next = temp->next;
                  temp->next = log;
                  
                  log_s = log_s->next;
                  log = log_s->next;
                 
                
            }
            else
            {
                  log = log->next;
                  log_s = log_s->next;
            }

    }


}

方法二(修改瑕疵):

//数据冒泡数据插入
void insert_sort_val(node *head)
{
    //排序部分
    node* p = head->next;
    int len = 0;
    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    int i, j;
    node* temp = head;
    node* log = head->next;
    node* log_s = head;



    for (i = 0; i < len - 1; i++)
    {
      log = head->next;
      log_s = head;
      for (j = 0; j < len - 1 - i; j++)
      {
            if (log->data > log->next->data) 
            {
                  // 交换 log 和 log->next 节点
                  node* temp = log->next; // temp 是 log 的下一个节点
                  log_s->next = temp; // log_s 指向 temp
                  log->next = temp->next; // log 指向 temp 的下一个节点
                  temp->next = log; // temp 指向 log

                  // 更新 log_s 和 log 指针
                  log_s = temp; // log_s 移动到 temp
            } 
            else 
            {
                  // 不需要交换,直接移动指针
                  log_s = log; // log_s 移动到 log
                  log = log->next; // log 移动到下一个节点
            }

      }


    }


}

这里贴出示例代码:

#include <stdio.h>
#include <stdlib.h>
//INSERT_FLAG宏值为1表示尾插入   0为头插入
#define INSERT_FLAG   1
typedef struct inode
{
      //数据域 以整型数据为例
      int data; 
      // 指向相邻的下一个结构体节点的指针
      //存放后缀节点地址
      struct inode * next;
}node;   //node == struct inode
node *initList(void);
void insert(node *head, node *new);
void display(node *head);
node *find_node(node *head, int find_data);
node * dele_node(node *head, int del_data);
node *modify_data(node *head, int data, int new_data);
void destroy(node *head);
void insert_sort(node *head, node *new);
node* show_ptr(node* head,int num);
void insert_sort(node *head, node *new);
void insert_sort_val(node *head);

int main(void)
{
      char ch;
      int find_data, new_data, del_data, data;
      //head变量用于存储头节点地址
      node *head, *new, *find, *del;
      head = initList();
      if(head == NULL)
            return -1;
      while(1)
      {
            printf("请输入对数组的操作:a-数据插入,p-显示操作,d-删除数据, s-修改数据,f-查找数据,y-销毁链表,q-退出系统\n");
            //在获取字符之前,缓冲区为空
            scanf("%c", &ch);
            if(ch == 'q')
                  break;
            switch (ch)
            {
            case 'a':
                  new = initList();
                  if(new == NULL)
                  {
                        return -1;
                  }
                  printf("new 节点地址:%p\n", new);    
                  printf("请输入数据:");
                  
                  scanf("%d", &new->data);
                  insert(head, new);
                  printf("插入成功\n");
                  break;
            case 's':
                  printf("请输入要被修改的数据\n");
                  scanf("%d", &data);
                  printf("请输入修改后的数据\n");
                  scanf("%d", &new_data);                
                  find = modify_data(head, data, new_data);
                  if(find == NULL)
                  {
                        printf("查无此要被修改的数据\n");
                  }
                  else
                  {
                        printf("修改成功\n");
                  }             
                  break;
            case 'd':
                  printf("请输入要删除的数据:");
                  scanf("%d", &del_data);
                  del = dele_node(head, del_data);
                  if(del == NULL)
                  {
                        printf("无此数据,无法删除\n");
                  }
                  else
                  {
                        printf("数据删除成功,删除节点地址:%p\n", del);
                  }
                  break;   
                  
            case 'f':
                  printf("请输入要查找的数据:");
                  scanf("%d", &find_data);
                  
                  find = find_node(head, find_data);
                  if(find == NULL)
                  {
                        printf("查无此数据\n");
                  }
                  else
                  {
                        printf("有此数据,数据节点地址:%p\n", find);
                  }
                  break;               
            case 'p':
                  display(head);
                  break;
            case 'y':
                  //保存头节点
                  destroy(head->next);
                  head->next = NULL;
                  break;
            default:
                  break;
            }
            //循环清空缓冲区
            while (getchar() != '\n');         
      }
      destroy(head);
}
void destroy(node *head)
{
      node *tmp,*p = head;
      while (p != NULL)
      {
            tmp = p;
            p = p->next;
            free(tmp);
      }
      
}
node *modify_data(node *head, int data, int new_data)
{
      node *find;
      find = find_node(head, data);
      if(find == NULL)
      {
            return NULL;
      }
      find->data = new_data;
      return find;
}
//节点删除--节点解除
node * dele_node(node *head, int del_data)
{
      node *del, *p;
      del = find_node(head, del_data);
      if(del == NULL)
      {
            return NULL;
      }
      p = head;
      //查找del前缀节点 
      while (p->next != del)
      {
            p = p->next;
      }
      
      //结合图示理解,将del从链表当中解下来
      p->next = del->next;
      del->next = NULL;
      return del;
}
//查找数据,返回节点地址(假设数据不同)
node *find_node(node *head, int find_data)
{
      node *p = head->next;
      for(; p != NULL; p=p->next)
      {
            if(p->data == find_data)
                  return p;
      }
      return NULL;
}
void display(node *head)
{
      insert_sort_val(head);
      node *p = head->next;
      //p != NULL 说明这个节点存在
      while(p != NULL)
      {
      
            printf("%d\t",p->data);
            p = p->next;
      }
      printf("\n");
}
//结构体指针函数      在堆空间生成新的一个节点
node *initList(void)
{
      //在堆空间开辟一块sizeof(node)大小的内存
      node *new = (node *)malloc(sizeof(node));    
      if(new == NULL)
      {
            printf("malloc failure\n");
            return NULL;
      }
      new->data = 0;
      new->next = NULL;
      return new;
}
//数据头插入
void insert(node *head, node *new)
{
#if INSERT_FLAG
      node *p = head;
      
      //p->next != NULL,p有后缀节点
      while(p->next != NULL)
      {
            p = p->next;
      }
      p->next = new;
#else
      new->next = head->next;
      head->next = new;
#endif
}
/*
void bubble_sort(node* head) 
{
    node* p = head;
    int len = 0;
    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    int i, j, temp;


    for (i = 0; i < len - 1; i++)
        for (j = 0; j < len - 1 - i; j++)
        if (show(head,j) > show(head,(j + 1)) )
            {
            temp = show(head,(j));
            allot(head,(j),show(head,(j+1)));
            allot(head,(j+1),temp);
            }
}
void allot(node* head,int num,int number)
{
    node* p = head;
    int i;
    for(i=0;i<num;i++)
    {
        p = p->next;
    }
    p->data = number; 
}

int show(node* head,int num)
{
    node* p = head;
    int i;
    for(i=0;i<num;i++)
    {
        p = p->next;
    }
    return p->data;
}



//数据冒泡数据插入
void insert_sort(node *head, node *new)
{
    //简单插入部分
    node *pt = head;
      
    //p->next != NULL,p有后缀节点
    while(pt->next != NULL)
    {
          pt = pt->next;
    }
    pt->next = new;


    //排序部分
    node* p = head;
    int len = 0;
    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    int i, j, temp;
    node* p1,*p2,*p3,*p4;



    for (i = 0; i < len - 1; i++)
        for (j = 0; j < len - 1 - i; j++)
        if (show(head,j) > show(head,(j + 1)) )
            {
                p1 = show_ptr(head,j);
                p2 = p1->next;
                p3 = p2->next;
                p4 = p3->next;
                p1->next = p3;
                p2->next = p4;
            }

}

node* show_ptr(node* head,int num)
{
    node* p = head->next;
    node* tmp = head;
    int i;
    for(i=0;i<num;i++)
    {
        p = p->next;
        tmp = tmp->next;
    }
    return tmp;
}

*/





//数据冒泡数据插入
void insert_sort_val(node *head)
{
    //排序部分
    node* p = head->next;
    int len = 0;
    while(p != NULL)
    {
        len++;
        p = p->next;
    }

    int i, j;
    node* temp = head;
    node* log = head->next;
    node* log_s = head;



    for (i = 0; i < len - 1; i++)
    {
      log = head->next;
      log_s = head;
      for (j = 0; j < len - 1 - i; j++)
      {

/*
            if (log->data > log->next->data )
            {
                  temp = log->next;
                  log_s->next = log->next;
                  log->next = temp->next;
                  temp->next = log;
                  
                  log_s = log_s->next;
                  log = log_s->next;
                 
                
            }
            else
            {
                  log = log->next;
                  log_s = log_s->next;
            }

*/
            if (log->data > log->next->data )
            {
                  //记录位置
                  temp = log->next;

                  //断开节点
                  log_s->next = log->next;
                  log->next = temp->next;
                  temp->next = log;
                  
                  //回退
                  log = log_s->next;
                 
                
            }

            log = log->next;
            log_s = log_s->next;

      }


    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值