(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;
}
}
}