在一个带头结点的单链表A中,自行输入A中的元素值,请实现:
(1)将链表A中值相同的结点,仅保留第一次出现的结点;
(2)将新得到的A链表,根据值的奇偶性进行拆分,拆分为有序的链表B和链表C。
B、C满足:链表B为值递增排序的奇数链表,链表C为值递增的偶数链表。
实验要求:
(1)实验顺序不能颠倒;
(2)每一小问完成后输出结果;
(3)对算法进行复杂性分析。
代码内容:
#include<iostream>
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <malloc.h>
using namespace std;
/*定义链表*/
typedef struct Node
{
int data;
struct Node* next;
}LinkList,*LNode;
/*给链表赋值并添加头节点*/
void create(LinkList*& A, int a[], int n) //传入链表A,数组a[],链表长度n
{
int i;
LinkList* s, * r;
A = (LinkList*)malloc(sizeof(LinkList)); //给链表A分配内存空间,同时产生头节点,将A指向此头节点
r = A;
for (i = 0; i < n; i++)
{
s = (LinkList*)malloc(sizeof(LinkList)); //给链表s分配内存空间,并插入节点
s->data = a[i]; //将数组a[]的值赋值给链表
r->next = s;
r = s;
}
r->next = NULL;
}
/*在单链表中删除值相同的多余结点*/
void deleteLinkList(LinkList*& A) //传入链表
{
LinkList* p = A->next, * s, * q;
while (p != NULL) //第一重循环将p的位置固定下来,进入第二重循环与后面的遍历指针p所指向的结点比较看值是否相等
{
q = p;//将q指向p的结点,比较数据的值是否相等
while (q->next != NULL) //用q遍历p之后的每一个结点
{
if (q->next->data == p->data) //如果q的值与p的值相同
{
s = q->next;//s保留需要删除的结点
q->next = s->next;//将需要删除的节点的前后结点相接
free(s);//将需要删除的结点释放
}
else
{
q = q->next;//如果q的值与p的值不相同,则q移向后一个结点
}
}
p = p->next;//将p移向后一个结点
}
}
/*打印链表*/
void print(LinkList* L)//传入链表
{
LinkList* p = L->next;
while (p != NULL) //链表结点对应的值不为空时打印值
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
/*拆分成奇数链表和偶数链表*/
LNode spilt(LinkList* B , LinkList* C)
{
LinkList* p = B;
C = (LinkList*)malloc(sizeof(LinkList)); //给链表C分配内存空间
C->next = NULL; //链表C结点为空
LinkList* q = C;
LinkList* r;
while (p->next != NULL)//将p结点不为空时
{
if (p->next->data % 2 == 0)//如果结点对应的值为偶数
{
r = p->next;//r保留这个偶数对应的结点
p->next = p->next->next;//将这个偶数前后的接连链接起来,即在原链表中删除这个偶数所对应的结点//q指针向下移动
q->next = r;//储存这个偶数对应的结点
r->next = NULL;//r结点为空
q = q->next; //将q移向后一个结点
}
else
{
p = p->next; //将p移向后一个结点
}
}
return C;//返回偶数链表B,且此时链表L已经成为一个奇数链表
}
/*对链表进行排序*/
void Sort(LinkList* L)
{
LinkList* p, * q;
int t;
p = L->next;//p指向首元结点
while (p != NULL)//第一重循环将p的位置固定下来,进入第二重循环与后面的遍历指针p所指向的结点之间相互比较大小
{
q = p->next;//将q指向p的下一个结点,进行数据之间的大小比较
while (q != NULL)//第二重循环就是不断将指针q后移,与p所指向的结点数据进行大小比较,数据互换
{
if (p->data > q->data)//冒泡排序
{
t = p->data;//将数据寄存在t中,进行互换
p->data = q->data;
q->data = t;
}
q = q->next;//遍历p之后的每一个值
}
p = p->next;//遍历链表中的每一个值
}
}
int main()
{
int n, i;
LinkList* A;//创建链表A
cout << "请输入链表A长度:" << endl;
cin >> n;//输入链表A的长度
cout << "请输入在链表A储存的数据:" << endl;
int a[1000];//创建数组a[]
for (i = 0; i < n; i++) //对数组A进行赋值
{
cin >> a[i];
}
create(A, a, n);//将数组a[]中的值传入链表A并添加头节点
cout << "对链表A去重并打印:" << endl;
deleteLinkList(A);//对链表A进行去重
print(A);//打印去重之后的链表A
LinkList* B = A;//创建与去重之后的链表A相等的链表B
LinkList* c = NULL ;//创建空链表c
LinkList* C = spilt(B, c);//创建链表C,将函数spilt()的返回值(偶数链表)赋值给链表C
//函数spilt()将链表B中的偶数所对应的结点删除,使链表B变成了奇数链表
cout << "对奇数链表B中的奇数排序并打印:" << endl;
Sort(B);
print(B);
cout << "对偶数链表C中的偶数排序并打印:" << endl;
Sort(C);
print(C);
return 0;
}
输出示例: