本随笔描述链表的重新排列和拆分。
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; } }