单链表确实是不好操作,只能顺着毛摸的感觉很不爽。
提示是用选择排序、插入排序或冒泡排序,其实这仨时间复杂度都是O(n^2),选哪个对效率影响不大。
我所以选择冒泡排序,是因为选择排序和插入排序都涉及到不相邻节点的对换问题,从D题可以看出,不相邻节点的对换涉及到四个节点的指针域的更改,而且相邻时反而要特别考虑,比较麻烦,
而冒泡排序一趟在中只涉及到相邻两个节点的比较和更改,相对而言比较方便。
冒泡排序中可能涉及到的节点交换
灵魂画师上线
画图想一想,只是多,不难
1、第一个节点和第二个节点
用prevPtr=NULL来标志第一个节点,此时!prevPtr为true
1)需要交换时:
isChanged标志位为1
头结点入口更改
a的节点域改成b的节点域
b的节点域改成a
2)不需要交换时
isChanged标志位仍然为0,啥也不干
根据isChanged标志位,指针迭代的方式也不同
更换过:b的节点域改成a的后继节点
标志位重置为0
没更换过:a和b各自向后平移一位
此时第一次的BUFF结束,prev被设置为头节点(头结点必须用*sPtr获取,因为头结点的位置可能会更改,用headPtr保存的话可能实际上变成了第二个节点)
2、一般情况
1)需要交换时:
isChanged设置为1
a的节点域改成b的节点域
prev的节点域改成b
b的节点域改成a
2)不需要交换时:
isChanged标志位仍然为0,啥也不干
根据isChanged标志位,指针迭代的方式也不同
更换过:isChanged重置为0
prev向后迭代
b成为a的后继
a成为prev的后继
没有更改:prev、a、b各自向后迭代
#include <stdio.h>
#include <stdlib.h>
typedef struct _node
{
int data;
struct _node* nextPtr;
} Node;
Node* createList();
void destoryList(Node** sPtr);
int lenList(Node **sPtr);//用于计算链表内的节点数
void bubbleSortList(Node **sPtr);
void printList(Node **sPtr);
int main(int argc, char const *argv[])
{
Node *headPtr=createList();
bubbleSortList(&headPtr);
printf(