码迷,mamicode.com
首页 > 编程语言 > 详细

揭开链表逆转和排序的面纱

时间:2015-05-05 16:26:20      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

 我们都知道,对于顺序表逆转和排序就如同数组一样,将数据改变位置就行,因为他们的数据是连续的空间存储的,但是对于链表如果你也这样只改变值进行排序,那你就太不懂链表的心了,链表的特点就是动态开辟游离的空间然后依据上一个节点所存的地址来寻找下一个节点,这样使得位置这个概念在链表里显得太不重要,所以对于链表我们如果想要逆转或者排序就是要改变每个节点里面存储的地址,通俗一点就是要改变指针的指向,于是我找到了一种将所有链表逆转和排序的统一算法:

(这里所说链表全是带有头节点链表)

简述算法步骤:1.将链表的第一个节点与后边的节点断开,(如果小于1个节点的链表就无需逆转和排序了:>)此时就会形成原链表和断出来的链表。

                     2.对于逆转,可以将断出来的链表的节点一个一个分别头插入原链表,对于排序,可以将断出来的链表的节点一个一个分别顺序插入原链表,所谓顺序插入就是再插入的时候会找到比自己大的数的前面进行插入(也可以找比自己小的数前面插入,这取决于如何排序),这个顺序插入可以用一个单独函数来实现。


具体分析与代码如下:(其实对于循环链表完全么有逆转的必要,但是为了练习,我们还是实现一下)

1.单链表的逆转与排序

技术分享

技术分享

技术分享

/**********************************************************************  
*   Copyright (c)2015,WK Studios
*   Filename:   S_List.h
*   Compiler: GCC,VS,VC6.0  win32  
*   Author:WK  
*   Time: 2015 2 5
**********************************************************************/
#ifndef _LIST_H
#define _LIST_H

#include<iostream>
using namespace std;
#include<assert.h>
#define  ElemType int

typedef struct Node
{
   ElemType data;
   struct Node *next;
}Node;

typedef struct List
{
 Node *first;
 Node *Last;
 size_t size;
}Mange;

//1.初始化单链表
void InitList (Mange *L);
//2.头插法
bool PushFront(Mange *L,ElemType e);
//3.显示
void Print(Mange *L);
//4.按值查找
Node* find_val(Mange *L,ElemType e);
//5.按顺序插入
bool insert_val(Mange *L, ElemType x);
//6.按位置逆转链表
bool Reverse_Val_List(Mange *L);
//7.按位置排序链表(从小到大)
bool Sort_Pos_List(Mange *L);
#endif
/**********************************************************************  
*   Copyright (c)2015,WK Studios
*   Filename:   S_List.cpp
*   Compiler: GCC,VS,VC6.0  win32  
*   Author:WK  
*   Time: 2015 2 5
**********************************************************************/
#include"List.h"
//1.初始化单链表
void InitList (Mange *L)
{
    Node *s=(Node*)malloc(sizeof(Node));
    assert(s != NULL);
    s->data=-1000000;//此处也可以放其他信息,这里表示没有放信息
    s->next=NULL;
	
    L->first=L->Last=s;
    L->size=0;
}
//2.头插法
bool PushFront(Mange *L,ElemType e)
{
	Node *s=(Node*)malloc(sizeof(Node));
	assert(s != NULL);
	s->data=e;
	s->next=L->first->next;
	L->first->next=s;
	
	if(L->size == 0)
    {
		L->Last=s;
    }
	L->size++;
	return true;
}
//3.显示
void Print(Mange *L)
{
	
	if(L->first->next==NULL)
	{
		cout<<"空链表!\n";
		return;
	}
	Node *p=L->first->next;
	while(p!= NULL)
    {
		cout<<p->data;
		if(p->next!=NULL)
		{
			cout<<"->";
		}
		p=p->next;
    }
	cout<<"\n";
	
}
//4.按值查找
Node* find_val(Mange *L,ElemType e)
{
    Node *p=L->first->next;
	while(p!=NULL && p->data!=e)
	{
		p=p->next;
	}
	return p;
}
//5.按顺序插入
bool insert_val(Mange *L, ElemType x)
{
    Node *p = find_val(L,x);
	Node *s = (Node *)malloc(sizeof(Node));
	assert(s != NULL);
	s->data = x;

	p = L->first;
	while(p->next != NULL)
	{
		if(x < p->next->data)
			break;
		p = p->next;
	}
    //插入p的后面
	
	s->next=p->next;
	p->next=s;
	if(p == L->Last)
	{
	   L->Last=s;
	}
	return true;
}
//6.按位置逆转链表
bool  Reverse_Val_List(Mange *L)
{
  if(L->size<2)
	{
		cout<<"只有1个或者0个节点,无需逆转!\n";
		return false;
	}
  Node *p=L->first->next;
  Node *q=p->next;
  
  L->Last=p;
  p->next=NULL;

  while(q!=NULL)
  {
	  p=q;     //注意顺序与后面指针的丢失
	  q=q->next;

	  PushFront(L, p->data);
     
  }
}

//7.按位置排序链表(从小到大)
bool Sort_Pos_List(Mange *L)
{
     if(L->size<2)
	{
		cout<<"只有1个或者0个节点,无需排序!\n";
		return true;
	}
	 Node *p=L->first->next;
	 Node *q=p->next;
     
	 L->Last=p;
	 p->next=NULL;
	 
	 while(q!=NULL)
	 {
	    p=q;
		q=q->next;
       insert_val(L,p->data);
	 }
  return true;
}

/**********************************************************************  
*   Copyright (c)2015,WK Studios
*   Filename:   Main.cpp
*   Compiler: GCC,VS,VC6.0  win32  
*   Author:WK  
*   Time: 2015 2 5
**********************************************************************/
#include"List.h"

int main()
{
    Mange  mylist;
    InitList(&mylist);
    int select=1;
    ElemType item;
	while(select)
	{
		cout<<"****************************************************\n";
		cout<<"*    [1]PushFront            [2]insert_val         *\n";
		cout<<"*    [3]Print                [4]Reverse_Posi_List  *\n";
		cout<<"*    [5]Sort_Pos_List        [0] Quit              *\n";
		cout<<"****************************************************\n";
		cout<<"Please input a number which is represent a operator you want to do:";
		cin>>select;
		switch(select)
		{
		case 1:
			cout<<"please input number you want to insert:(end of number is -1)";
			while(cin>>item,item!=-1)
			{
				PushFront(&mylist,item);
			}
			break;
		case 2:
			cout<<"please input number you want to insert:(end of number is -1)";
			while(cin>>item,item!=-1)
			{
				insert_val(&mylist,item);
			}
			break;
		case 3:
			Print(&mylist);
			break;
		case 4:
			Reverse_Val_List(&mylist);
			break;
		case 5:
		   Sort_Pos_List(&mylist);
			break;
		default:
		    cout<<"Thank you for using !\n";	
			break;
			
		}
		
	}
	
	return 0;
}


2.单循环链表的逆转与排序

技术分享

技术分享

技术分享


3.双链表的逆转与排序

技术分享

技术分享

技术分享

4.双循环链表的逆转与排序

技术分享

技术分享

技术分享

揭开链表逆转和排序的面纱

标签:

原文地址:http://blog.csdn.net/kai8wei/article/details/45503611

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!