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

来源:互联网 发布:中山门淘宝街怎么样 编辑:程序博客网 时间:2024/06/07 08:44

简要说下思路:

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



1 0
原创粉丝点击