持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
相关文章
基础知识
- 线性表
- 定义:线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。
- 存储形式:顺序存储(数组实现)、链式存储(链表实现)
题目
- 用随机函数生成10个3位整数(100~999),把这些整数存于单链表中,然后读入一个整数,以该值为基准把单链表分割为两部分,所有小于该值的结点排在大于或等于该值的结点之前。
思路
①实现单链表的常规操作:插入结点、链表判空、打印链表操作
②在上述操作的基础上,根据题目要求,遍历链表,比较结点大小,交互结点的数据,从而实现要求的链表分割功能
代码
#include <iostream>
#include <ctime>
using namespace std;
//======================================单链表============================================
class ListNode
{
public:
ListNode() :data(-1), next(NULL) {}
ListNode(int m_data, ListNode* m_next = NULL) :data(m_data), next(m_next) {}
~ListNode() { next = NULL; } //注意:此处不能写成delet next,否则会导致链表在删除结点时把链表后面的所有结点的指针丢失!!!
public:
int data;
ListNode* next;
};
class SingleList
{
public:
SingleList() :head(new ListNode()), len(0) {}
~SingleList() {}
void ListEmpty();
bool ListInsert(int item, int n);
void ListDivision(int base);
void ListPrint();
public:
ListNode* head;
int len;
};
void SingleList::ListEmpty()
{
ListNode* p;
while (head->next != NULL)
{
p = head->next;
head->next = p->next;
delete p;
}
}
bool SingleList::ListInsert(int item, int n) //插入item,位置n
{
if (n <= 0 || n > len + 1) // //链表下标从1开始
{
cout << "插入的位置非法!\n";
return 0;
}
ListNode *pmove = head;
ListNode *pnode = new ListNode(item);
for (int i = 1; i < n && pmove; i++) //移动指针到插入位置n的前一个位置n-1
{
pmove = pmove->next;
}
len++;
pnode->next = pmove->next; //插入的结点的next指向原来位置n的结点
pmove->next = pnode; //结点n-1的next指向新增结点
cout << "在第" << n << "位插入" << item << "成功!\n";
return 1;
}
void SingleList::ListDivision(int base)
{
SingleList* newList = new SingleList();
newList->ListInsert(base, 1); //插入基准结点
ListNode* basePrePos = newList->head; //获取基准位置的前一个结点的指针,basePrePos->next为base的指针
ListNode *pmove = head->next;
for (int pos = 1; pos <= len; ++pos) //遍历读取原链表元素
{
int item = pmove->data;
pmove = pmove->next;
if (item < base)
{
ListNode* newNode = new ListNode(item);
newNode->next = basePrePos->next;
basePrePos->next = newNode; //注意这两行代码,否则会造成原本的结点丢失
basePrePos = newNode;
}
else
{
ListNode* newNode = new ListNode(item);
newNode->next = basePrePos->next->next;
basePrePos->next->next = newNode;
}
}
newList->ListPrint();
cout << "删除基准结点...\n";
ListNode* pp = newList->head;
while (pp->next != NULL)
{
if (pp->next->data == base)
{
ListNode* tmp = pp->next;
pp->next = pp->next->next;
delete tmp;
break;
}
pp = pp->next;
}
//打印链表
newList->ListPrint();
cout << "链表分割完成!" << endl;
}
void SingleList::ListPrint()
{
ListNode* p = head->next;
if (p == NULL) cout << "链表为空!" << endl;
else
{
cout << "链表元素为:Start";
while (p != NULL)
{
cout << "->" << p->data;
p = p->next;
}
cout << "->End" << endl;
}
}
//=====================测试1======================
void test1()
{
cout << "=====================测试1 单链表操作======================\n";
time_t t;
srand((unsigned)time(&t));
SingleList Slist; //定义一个单链表
for (int i = 1; i <= 10; i++) //生成10个随机整数存入链表
{
Slist.ListInsert(rand() % 900 + 100, i); //插入到位置i100-999随机整数
}
Slist.ListPrint();
int base;
cout << "\n执行分割链表的操作...\n";
cout << "请输入基准整数:";
cin >> base;
Slist.ListDivision(base);