- 将两个递增的有序列表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用存储空间。表中不允许有重复的数据。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
Node* combine(Node* list1, Node* list2) {
Node* head = list1;
Node* tail = list1;
list1 = list1->next;
list2 = list2->next;
while (list1 != 0 && list2 != 0)
{
if (list1->data < list2->data) {
tail->next = list1;
tail = tail->next;
list1 = list1->next;
}
else if (list1->data == list2->data) {
tail->next = list1;
tail = tail->next;
Node* temp = list2;
list1 = list1->next;
list2 = list2->next;
delete temp;
}
else {
tail->next = list2;
tail = tail->next;
list2 = list2->next;
}
}
if (list1 != 0) {
tail->next = list1;
}
if (list2 != 0) {
tail->next = list2;
}
return head;
}
int main() {
Node list1, list2;
add(&list1, new Node(1));
add(&list1, new Node(2));
add(&list1, new Node(3));
add(&list1, new Node(4));
add(&list1, new Node(5));
add(&list2, new Node(3));
add(&list2, new Node(5));
add(&list2, new Node(7));
add(&list2, new Node(8));
add(&list2, new Node(9));
display(&list1);
display(&list2);
Node* combined = combine(&list2, &list1);
display(combined);
clear(combined);
return 0;
}
2. 将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用存储空间。表中允许有重复的数据。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
Node* combine(Node* list1, Node* list2) {
Node* head = list1;
Node* tail = list1;
list1 = list1->next;
list2 = list2->next;
while (list1 != 0 && list2 != 0)
{
if (list1->data <= list2->data) {
tail->next = list1;
tail = tail->next;
list1 = list1->next;
}
else {
tail->next = list2;
tail = tail->next;
list2 = list2->next;
}
}
if (list1 != 0) {
tail->next = list1;
}
if (list2 != 0) {
tail->next = list2;
}
return head;
}
void reverse(Node* head) {
Node* lastItem = 0;
for (Node* i = head->next; i != 0; ) {
Node* temp = i;
i = i->next;
if (temp->next == 0) {
head->next = temp;
}
temp->next = lastItem;
lastItem = temp;
}
}
int main() {
Node list1, list2;
add(&list1, new Node(1));
add(&list1, new Node(2));
add(&list1, new Node(3));
add(&list1, new Node(4));
add(&list1, new Node(5));
add(&list2, new Node(3));
add(&list2, new Node(5));
add(&list2, new Node(7));
add(&list2, new Node(8));
add(&list2, new Node(9));
display(&list1);
display(&list2);
Node* combined = combine(&list2, &list1);
reverse(combined);
display(combined);
clear(combined);
return 0;
}
3. 已知链表A和B分表表示两个集合,其元素递增排列。请设计一个算法,用于求出A和B交集并存放在A链表中。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
void intersect(Node* list1, Node* list2) {
Node* p1 = list1->next;
Node* p2 = list2->next;
while (p1 != 0 && p2 != 0)
{
if (p1->data < p2->data) {
Node* temp = p1;
p1 = p1->next;
delete temp;
}
else if (p1->data > p2->data) {
p2 = p2->next;
}
else {
list1->next = p1;
list1 = list1->next;
p1 = p1->next;
p2 = p2->next;
}
}
list1->next = 0;
}
int main() {
Node list1, list2;
add(&list1, new Node(1));
add(&list1, new Node(2));
add(&list1, new Node(3));
add(&list1, new Node(4));
add(&list1, new Node(5));
add(&list2, new Node(3));
add(&list2, new Node(5));
add(&list2, new Node(7));
add(&list2, new Node(8));
add(&list2, new Node(9));
display(&list1);
display(&list2);
intersect(&list2, &list1);
display(&list2);
clear(&list1);
clear(&list2);
return 0;
}
4.已知链表A和B分表表示两个集合,其元素递增排列。请设计算法求出两个集合A和B的差集(即仅由在A中出现而不在B中出现的的元素所构成的集合),并以同样的形式存储,同时返回该集合元素的个数。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
int substract(Node* list1, Node* list2) {
Node* p1 = list1->next;
Node* p2 = list2->next;
int count = 0;
while (p1 != 0 && p2 != 0)
{
if (p1->data < p2->data) {
list1->next = p1;
list1 = list1->next;
count++;
p1 = p1->next;
}
else if (p1->data > p2->data) {
p2 = p2->next;
}
else {
Node* temp = p1;
p1 = p1->next;
p2 = p2->next;
delete temp;
}
}
while (p1 != 0)
{
list1->next = p1;
list1 = list1->next;
p1 = p1->next;
count++;
}
list1->next = 0;
return count;
}
int main() {
Node list1, list2;
add(&list1, new Node(1));
add(&list1, new Node(2));
add(&list1, new Node(3));
add(&list1, new Node(4));
add(&list1, new Node(5));
add(&list2, new Node(3));
add(&list2, new Node(5));
add(&list2, new Node(7));
add(&list2, new Node(8));
add(&list2, new Node(9));
display(&list1);
display(&list2);
int count = substract(&list2, &list1);
display(&list2);
cout << "remain size: " << count << endl;
clear(&list1);
clear(&list2);
return 0;
}
5. 设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B和C,其中B表的结点为A表中值小于0的结点,而C表的结点为A表中值大于0的结点(链表A中的元素为非0整数,要求B、C表利用A表的结点)。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
void split(Node* head, Node* list1, Node* list2) {
for (Node* i = head->next; i != 0; i = i->next)
{
if (i->data < 0) {
list1->next = i;
list1 = list1->next;
}
else {
list2->next = i;
list2 = list2->next;
}
}
head->next = 0;
list1->next = 0;
list2->next = 0;
}
int main() {
Node head, list1, list2;
add(&head, new Node(-1));
add(&head, new Node(5));
add(&head, new Node(-2));
add(&head, new Node(6));
add(&head, new Node(-3));
add(&head, new Node(7));
add(&head, new Node(-4));
display(&head);
split(&head, &list1, &list2);
display(&list1);
display(&list2);
clear(&list1);
clear(&list2);
return 0;
}
- 设计一个算法,通过一趟遍历确定长度为n的单链表中值最大的结点,返回该结点的数据域。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
int max(Node* head) {
head = head->next;
int maxValue = head->data;
while (head != 0)
{
if (head->data > maxValue) {
maxValue = head->data;
}
head = head->next;
}
return maxValue;
}
int main() {
Node head;
add(&head, new Node(-1));
add(&head, new Node(5));
add(&head, new Node(-2));
add(&head, new Node(6));
add(&head, new Node(-3));
add(&head, new Node(7));
add(&head, new Node(-4));
display(&head);
cout << "max in it: " << max(&head) << endl;
clear(&head);
return 0;
}
7. 设计一个算法,将链表中所有结点中的链接方向原地逆转,即要求利用原表中的存储空间,换句话说,要求算法的空间复杂度为O(1)。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
void reverse(Node* head) {
Node* last = 0;
Node* curr = head->next;
while (curr != 0) {
Node* temp = curr;
curr = curr->next;
temp->next = last;
last = temp;
if (curr == 0) {
head->next = temp;
}
}
}
int main() {
Node head;
add(&head, new Node(-1));
add(&head, new Node(5));
add(&head, new Node(-2));
add(&head, new Node(6));
add(&head, new Node(-3));
add(&head, new Node(7));
add(&head, new Node(-4));
display(&head);
reverse(&head);
display(&head);
clear(&head);
return 0;
}
8.设计一个算法,删除递增有序链表
中值大于mink且小于maxk(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)的所用元素。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* next;
Node(int data = 0, Node* next = 0): data(data), next(0) {
}
};
void add(Node* head, Node* node) {
for (Node* i = head; i != 0; i = i->next) {
if (i->next == 0) {
i->next = node;
break;
}
}
}
void clear(Node* head) {
while (head->next != 0) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
}
}
void display(Node* head) {
head = head->next;
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
void removeBetween(Node* head, int mink, int maxk) {
while (head->next != 0)
{
if (head->next->data > mink&& head->next->data < maxk) {
Node* temp = head->next;
head->next = head->next->next;
delete temp;
continue;
}
head = head->next;
}
}
int main() {
Node head;
add(&head, new Node(1));
add(&head, new Node(5));
add(&head, new Node(10));
add(&head, new Node(16));
add(&head, new Node(29));
add(&head, new Node(50));
add(&head, new Node(1000));
display(&head);
removeBetween(&head, 10, 51);
display(&head);
clear(&head);
return 0;
}
9.已知p指向双向循环链表中的一个结点,基结点结构为data、prior、next三个域,写出算法Exchange§,交换p所指向的结点及其前驱结点的的顺序。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Node {
public:
int data;
Node* prior;
Node* next;
Node(int data = 0) : data(data) {
this->prior = this;
this->next = this;
}
};
void add(Node* head, Node* node) {
Node* before = head->prior;
Node* after = head;
node->prior = before;
node->next = after;
before->next = node;
after->prior = node;
}
void clear(Node* head) {
while (head->next != head)
{
Node* temp = head->next;
Node* before = head;
Node* after = head->next->next;
delete temp;
before->next = after;
after->prior = before;
}
}
void display(Node* head) {
Node* curr = head->next;
while (curr != head)
{
cout << curr->data << " ";
curr = curr->next;
}
cout << " <> ";
Node* curb = head->prior;
while (curb != head)
{
cout << curb->data << " ";
curb = curb->prior;
}
cout << endl;
}
void moveForward(Node* head, Node* node) {
//drop
node->prior->next = node->next;
node->next->prior = node->prior;
//insert
node->prior = node->prior->prior;
node->next = node->next->prior;
node->prior->next = node;
node->next->prior = node;
}
int main() {
Node head;
add(&head, new Node(1));
add(&head, new Node(3));
Node* five = new Node(5);
add(&head, five);
add(&head, new Node(7));
add(&head, new Node(9));
display(&head);
moveForward(&head, five);
display(&head);
clear(&head);
return 0;
}
10.已知长度为n的经线性表A采用顺序存储结构,请写出时间复杂度为O(n),空间复杂度为O(1)的算法,该算法可以删除线性表中所有值为item的数据元素。
#include <iostream>
#include <string>
#include <iomanip>
#include <array>
using namespace std;
void remove(int table[], int& size, int k) {
int count = 0;
for (int i = 0; i < size; i++) {
if (table[i] == k) {
count++;
}
else {
table[i - count] = table[i];
}
}
size -= count;
}
void display(int table[], int size) {
for (int i = 0; i < size; i++) {
cout << table[i] << " ";
}
cout << endl;
}
int main() {
int table[] = { 1, 3, 5, 7, 9, 7, 3, 2, 4, 3, 7, 6 };
int size = 12;
display(table, size);
remove(table, size, 7);
display(table, size);
return 0;
}