双向链表(非循环)排序
来源:互联网 发布:矩阵式项目管理 编辑:程序博客网 时间:2024/05/21 18:47
双向链表的操作问题
Description
建立一个长度为n的带头结点的双向链表,使得该链表中的数据元素递增有序排列。(必须使用双向链表完成,数据类型为整型。)
Input
第一行:双向表的长度;
第二行:链表中的数据元素。
Output
输出双向链表中的数据元素的值。
Sample Input
1
2
3
10
2 4 6 3 5 8 10 21 12 9
Sample Output
2 3 4 5 6 8 9 10 12 21
方案一:不带头结点的双链表排序
链表的创建及元素的存储不难,难的是对元素的排序,对链表进行排序,就好做好对每一个节点的处理,这儿我采用的是插入排序,每次选出最小值的节点,将其从链表中删除,再将其按顺序插入到前面,依次实现排序。难点是对第一个节点的和最后一个节点的处理代码如下:
#include<iostream>#include <stdlib.h>using namespace std;struct node{ int data; node *next,*pro;};int main(){ int n,i; cin>>n; node *head=NULL,*q,*p,*t; //创建双向链表,存储数据 for(i=0;i<n;i++) { p=(node *)malloc(sizeof(node)); p->next=p->pro=NULL; cin>>p->data; if(head==NULL) { q=head=p; } else { q->next=p; p->pro=q; q=p; } } //选择排序 for(i=0;i<n;i++) { int min=0x3f3f3f3f; if(i==0)//第一次遍历从头结点遍历,之后每次遍历从未排序的第一个节点(q节点的下一个节点)遍历 t=q=head; //q记录排序好的节点的最后一个节点的位置 else t=q->next; while(t!=NULL) //找出最小的节点 { if(t->data<min) { min=t->data; p=t; //用p指针记录当前未排序节点的最小值节点的位置 } t=t->next; } //将p节点独立出来 if(p->pro==NULL||p->pro==q)//p是未排序的第一个节点 { q=p; //后移一位即可 continue; } else if(p->next==NULL) //p是最后一个节点(要先判断是否是第一个未排序节点(处理该节点既是未排序节点又是尾节点)) p->pro->next=NULL; //先判断是首个未排序节点可以避免将已排序节点的后继指针赋值为空,造成链表从中间断裂 else//中间的节点 { p->pro->next=p->next; p->next->pro=p->pro; } //将p节点重新连接到前面 if(i==0) //首个排序节点单独处理 { head->pro=p; //第一个节点前继指针记录插入的p节点的位置 p->next=head;//p节点后继指针记录第一个节点的位置 p->pro=NULL; //p节点前继指针置空 head=p; //头指针指向p q=p; //q指向p(为下次循环准备) } else { q->next->pro=p; p->next=q->next; q->next=p; p->pro=q; q=p; } } t=head; while(t!=NULL) { cout<<t->data<<" "; t=t->next; } return 0;}
方案二:
带头结点的双链表排序,也是选择排序,非常方便
#include <iostream>#include <stdlib.h>using namespace std;typedef struct node{ int data; node *next,*pri;}LinkNode,*LInkList;int main(){ LInkList head,p,t,q; head=(LInkList)malloc(sizeof(LinkNode)); head->next=head->pri=NULL; int n,i;cin>>n; //创建双链表 for(i=0;i<n;i++) { p=(LInkList)malloc(sizeof(LinkNode)); p->next=p->pri=NULL; cin>>p->data; if(head->next==NULL) head->next=q=p; else { q->next=p; p->pri=q; q=p; } } //直接插入排序 q=head->next->next;//q指向第一个节点的指针域(当不只有一个节点时指向第二个节点) head->next->next=NULL;//断开第一个节点和之后节点的联系 while(q!=NULL)//依次取出断开链表的第一个结点向有序链表中插入 { p=q->next; t=head; while(t->next!=NULL&&t->next->data<q->data)//找出插入点 t=t->next; q->next=t->next;//插入 t->next=q; q=p;//指向断开链表的下一个点(当前断开链表的第一个结点) } t=head; while(t->next!=NULL) { cout<<t->next->data<<' '; t=t->next; } return 0;}
可以看出,加个头结点还是非常方便的= =
1 0
- 双向链表(非循环)排序
- 双向链表(非循环)
- 双向链表(非循环)
- 数据结构--双向非循环链表
- 经典算法学习——非循环双向链表实现冒泡排序(不带头结点)
- 经典算法学习——非循环双向链表实现冒泡排序(带头结点尾结点)
- 循环双向链表及快速排序
- 双向循环链表的冒泡排序
- 双向循环链表的选择排序
- 双向循环链表的插入排序
- C语言使用非循环双向链表实现队列
- 双向非循环链表(没有头结点)
- 数据结构学习之双向循环链表的基本操作(非递归实现)
- C语言实现双向非循环链表(不带头结点)的基本操作
- C语言实现双向非循环链表(不带头结点)的逆序打印
- C语言实现双向非循环链表(不带头结点)的节点插入
- C语言实现双向非循环链表(不带头结点)的清空
- C语言实现双向非循环链表(带头结点尾结点)的基本操作
- 安装Ubuntu12.04以及sources.list更新源推荐
- 欢迎使用CSDN-markdown编辑器
- C++内存管理
- 骚鸟、骚七能不能超神
- Redis、Memcached简单封装
- 双向链表(非循环)排序
- 虚拟机怎么安装vmware tools
- 卷积神经网络(CNN)就是这么简单
- Conversion to Dalvik format failed with error 1 in Android on export
- android中属性动画 ObjectionAnimation
- 让MVC的参数可以为.jpg待静态文件
- Hbase总结
- Ack 框架分析
- 【HTML5】具有boolean值的属性