本随笔描述链表的重新排列和拆分。
4)不带头结点的链表,要求将链表按数据域的值从小到大重新链接。不能使用额外的结点空间。
本题有一定难度
#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Listnode,*LinkList;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
void Sort(LinkList &La)//使用直接插入排序算法
{
LinkList p=La->next;//p为工作指针,指向待排序的当前元素
La->next = NULL;//假设第一个元素有序,即链表中现在只有一个结点
while(p)
{
LinkList r=p->next;//r是p的后继
LinkList q=La;
if(q->data>=p->data)//处理待排序结点p比第一个元素结点小的情况
{
p->next=La;
La=p;//链表指针指向最小元素
}
else
{
while(q->next&&q->next->data<p->data)//查找结点p的插入位置
{
q=q->next;
}
p->next=q->next;//将当前排序结点链入有序链表中
q->next=p;
}
p=r;//p指向下个待排序的结点
}
}
5)【链表拆分】带头结点的链表分解为小于0和大于0的两个链表,其中要求利用原链表的结点。此法将结点插到头结点后面。
#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Listnode,*LinkList;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
void Sort(LinkList &La)
{
LinkList p=La->next;//p为工作指针
LinkList Lb=La,Lc=(LinkList)malloc(sizeof(Listnode));
Lb->next=NULL;Lc->next=NULL;
while(p)
{
LinkList r=p->next;//存储p的后继
if(p->data<0)
{
p->next=Lb->next;
Lb->next=p;
}
if(p->data>0)
{
p->next=Lc->next;
Lc->next=p;
}
p=r;
}
}
6)【链表分解】带头结点呢的链表分解成表A和表B,分解后的A表含有原表序号为奇数的元素,B表含有原表序号为偶数的元素。要求分解后两表中元素结点的相对顺序不变,故采用尾插法。
#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Listnode,*LinkList;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
void Sort(LinkList &La)
{
int i=0;
LinkList p=La->next;//p为工作指针
LinkList Lb=(LinkList)malloc(sizeof(Listnode));
Lb->next=NULL;
LinkList ra,rb;//指向将要创建新表的尾结点
ra=La;rb=Lb;
La->next=NULL;
while(p)
{
i++;
LinkList r=p->next;//存储p的后继
if(i%2==0)
{
p->next=rb->next;
rb->next=p;
rb=p;
}
else
{
p->next=ra->next;
rb->next=p;
rb=p;
}
p=r;
}
}