题目描述
给定n个整数,按输入顺序建立单链表,删除其中的重复数字,输出结果链表。(要求不可以构建新结点,不可以定义新链表。在原链表上删除。)
输入
测试次数t
每组测试数据一行:
n(表示有n个整数),后跟n个数字
输出
对每组测试数据,输出删除重复数字后的结果链表表长和每个元素,具体格式见样例。
输入样例1
3
10 1 2 3 4 1 2 10 20 30 20
5 1 1 1 1 1
6 20 22 22 22 22 20
输出样例1
7: 1 2 3 4 10 20 30
1: 1
2: 20 22
示例代码:
#include<iostream>
using namespace std;
class ListNode
{
public:
int data;
ListNode* next;
ListNode()
{
next = NULL;
}
};
class LinkList
{
public:
ListNode* head;
int len;
LinkList()
{
head = new ListNode();
len = 0;
}
~LinkList()
{
ListNode* p, * q;
p = head;
while (p != NULL)
{
q = p;
p = p->next;
delete q;
}
len = 0;
head = NULL;
}
void LL_display(int n) //输出
{
ListNode* p;
p = head->next;
cout << len+n << ": ";
for(int i=1;i<=len+n;i++)
{
if (i != len + n) //当一行的最后一个数字输出之后,不要加空格
{
cout << p->data << " ";
p = p->next;
}
else
{
cout << p->data;
}
}
}
void create(int LEN) //创建单链表
{
ListNode* p, * q;
p = head; //p指向头结点
for (int i = 0;i < LEN;i++)
{
q = new ListNode();
cin >> q->data;
p->next = q;
p = q;
}
p->next = NULL;
}
};
void deletesame(LinkList &L) //删除相同的结点,这里传入要删的链表
{
ListNode* p, * q, * s;
p = L.head->next; //p指向第一个结点
for (p;p != NULL;p = p->next) //遍历整个链表,如果p不为空就执行比较,之后指向下一个结点
{
s = p; //s指向p,这里s的作用是指向要删除的点的前驱
for (q = p->next;q != NULL; ) //q指向p的下一个结点,当q不为空时,进行比较,即用两个循环进行p和之后的所有结点比较
{
if (p->data == q->data)
{
s->next = q->next; //s的下一个结点改为原来q的下一个结点
delete q; //删去q
q = s->next; //再让q指向s的下一个结点,方便继续遍历
L.len--;
}
else
{
s = q; //s指向p
q = q->next; //p指向自己的下一个结点,即s和p保持一前一后地向后移动
}
}
}
}
int main()
{
int t;
cin >> t;
for (int i = 1;i <= t;i++)
{
int n;
cin >> n;
LinkList L;
L.create(n);
deletesame(L);
if (i < t)
{
L.LL_display(n);
cout << endl;
}
else if(i==t)
{
L.LL_display(n); //最后一行不换行
}
}
}
一点想法:
还有一个疑问,这道题目中我按照输入样例输入后输出的链表长度len始终为负数,且刚好len+n就是删减后的链表长度,想了半天没想明白,希望大家指导 。