您的位置:首页 > 理论基础 > 数据结构算法

链表的总结(链表排序、翻转、删除节点)

2017-04-22 16:55 375 查看
简要说下思路:

node* sort_linklist(node *head){//链表排序(类比选择排序)
node *sortedarray,*previous,*temp;
for (int i=1; i<=n; i++) {
sortedarray=creatnode();
sortedarray->data=selectmm_linklist(head);
if (i==1) {
temp=previous=sortedarray;
}
else{
previous->next=sortedarray;
}
delete_linklist(head, sortedarray->data);//delete会自动删除链表中元素至链表中元素个数为0,就退出while循环
previous=sortedarray;
}
return temp;
}


1.链表排序(代码如上)

我采用的排序方法是直接用类似于数据结构中的选择排序的方法,首先找出优先级最大的数字,在我的代码里面最小的数字具有最大的优先级,需要注意的是:选择排序为了进行多次扫描,必须要把那个最小的元素从链表中删除,因为它并不等同于数组(数组的话能直接把最小的那个元素直接放在最前的位置,但是链表如果这样操作的话就太麻烦了),每次我们取出的那一个数我们就把它直接放入新的链表里面,只需要放在最后的位置就行了,因为我们每次取的数字都优先级一次比一次小(比如3,2,1变成1,2,3),当排序成功了,新的链表的节点个数就为n了,而之前的链表为空了,因为之前链表里面的值都转到了新的排好序的链表了.

node* reverse_linklist(node *head){//from a->b->c to a<-b<-c,3个指针(current,head,previous)实现链表翻转
node *previous=NULL,*current=head;
while (1) {//在循环里面的话head其实代表的是后继指针
head=head->next;//这句话肯定没次都要执行
current->next=previous;//修改current指针
previous=current;
if (!head) {
return current;
}
current=head;//头指针变为current
}
}


2.链表翻转(代码如上)

链表翻转的话,我觉得容易出错的地方就是指针的记录吧,注意一下链表的特性,链表具有递进的结构,a->b->c->d->null,翻转后它变为null-<a-<b-<c-<d,我们肯定要从头开始翻转,但是如果我们直接修改a的next指针的话整个链表就丢失了(我一直觉得头指针是一个链表最重要的部分,没有头指针,链表就丢了,就想没有思想没有头脑的人找不到自己的归属),所以我们需要通过另外一个指针来存b->c->d->null这部分,存完以后就可以执行循环了,注意终止条件是head=null,因为head=null的时候current正好在最后一个元素,此时最后一个元素就是头指针了,返回current就可以直接通过current访问翻转后的链表了.

3.下面直接贴一下所有的代码吧,里面有详细的实现算法的过程.

#include "iostream"
#include "cstdlib"
using namespace std;
struct node{
int data;
node *next;
};
node *head;int n;
node *creatnode(){//创建节点
node *e;
e=(node*)malloc(sizeof(node));
e->next=NULL;
return e;
}
void init(node *&head){//初始化链表,*&表示对指针的引用,注意一下引用在函数体返回的时候head值会改变,类比swap中的引用
node *previous,*current;
previous=current=NULL;
int a;
cin>>n;
for (int i=1; i<=n; i++) {
cin>>a;
current=creatnode();
current->data=a;
if (i==1) {
head=current;
}
else{
previous->next=current;
}
previous=current;
}
}
void get_linklist(node *head){//输出链表所有元素
while (head) {
cout<<head->data<<' ';
head=head->next;
}
cout<<endl;
}
node* reverse_linklist(node *head){//from a->b->c to a<-b<-c,3个指针(current,head,previous)实现链表翻转 node *previous=NULL,*current=head; while (1) {//在循环里面的话head其实代表的是后继指针 head=head->next;//这句话肯定没次都要执行 current->next=previous;//修改current指针 previous=current; if (!head) { return current; } current=head;//头指针变为current } }
void delete_linklist(node *&head,int val){//删除链表中某个节点
node *previous,*temp;
temp=head;
if (head->data==val) {
head=head->next;
}
else{
while (temp) {
if (temp->data==val) {
previous->next=temp->next;
break;
}
previous=temp;
temp=temp->next;
}
}
}
int selectmm_linklist(node *head){
int min=1000000;
while (head) {
if (head->data<min) {
min=head->data;
}
head=head->next;
}
return min;
}
node* sort_linklist(node *head){//链表排序(等同于选择排序)
node *sortedarray,*previous,*temp;
for (int i=1; i<=n; i++) {
sortedarray=creatnode();
sortedarray->data=selectmm_linklist(head);
if (i==1) {
temp=previous=sortedarray;
}
else{
previous->next=sortedarray;
}
delete_linklist(head, sortedarray->data);//delete会自动删除链表中元素至链表中元素个数为0,就退出while循环
previous=sortedarray;
}
return temp;
}
int main(){
init(head);
get_linklist(head);
get_linklist(reverse_linklist(head));
head=sort_linklist(head);
// delete_linklist(head, 1);
get_linklist(head);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 数据结构 算法
相关文章推荐