为了解决一个单片机项目的需求,解决频繁地跳转到某地址执行指令的问题,需要使用并维护一个序列
刚开始实在想不出办法,查了很多资料,也都用不上,后来知道链表结构的存在才解决了这个问题,花了一天半的时间从无到有接触单链表,记录一下基本操作集合,其中大部分都可以用来解决我单片机项目的问题
操作集
class LNode {
public:
int data;
LNode *next;
public:
explicit LNode(int x = -1) {
this->data = x;
this->next = nullptr;
}
~LNode() {
this->next = nullptr;
}
void DestroyList();
void Traverse();
void Delete_X(ElemType X);
LNode *Reverse();
void Delete_Min();
void SortLinkedList();
void Delete_S_2_E(ElemType Start, ElemType End);
void FindFirstCommonNode(LNode *L);
void SortLinkedList_NoTmpSpace();
void Divide_Odd_Even();
void MakeElemsUnique();
void Merge2LinkList_Dec(LNode *L2);
void Merge2LinkList_Inc(LNode *L2);
void Get2LinkListsIntersection(LNode *L2);
bool IsSuccessiveSeq(LNode *B);
bool FindReverseKthElem(unsigned int K);
void MakeElemsUniqueAbs(unsigned int dataRange);
private:
static unsigned int Partition(ElemType A[], unsigned int low, unsigned int high);
static void QuickSort(ElemType A[], unsigned int low, unsigned int high);
unsigned int GetLength();
LNode *FindMin();
};
源代码
#include <iostream>
#include <algorithm>
#define abs(a) (a >= 0) ? a : (0 - a)
using namespace std;
typedef int ElemType;
class LNode {
public:
int data;
LNode *next;
public:
explicit LNode(int x = -1) {
this->data = x;
this->next = nullptr;
}
~LNode() {
this->next = nullptr;
}
void DestroyList();
void Traverse();
void Delete_X(ElemType X);
LNode *Reverse();
void Delete_Min();
void SortLinkedList();
void Delete_S_2_E(ElemType Start, ElemType End);
void FindFirstCommonNode(LNode *L);
void SortLinkedList_NoTmpSpace();
void Divide_Odd_Even();
void MakeElemsUnique();
void Merge2LinkList_Dec(LNode *L2);
void Merge2LinkList_Inc(LNode *L2);
void Get2LinkListsIntersection(LNode *L2);
bool IsSuccessiveSeq(LNode *B);
bool FindReverseKthElem(unsigned int K);
void MakeElemsUniqueAbs(unsigned int dataRange);
private:
static unsigned int Partition(ElemType A[], unsigned int low, unsigned int high);
static void QuickSort(ElemType A[], unsigned int low, unsigned int high);
unsigned int GetLength();
LNode *FindMin();
};
void Create(LNode *&L) {
ElemType num;
cin >> num;
auto p = L;
while (num != -1) {
auto ins = new LNode(num);
p->next = ins;
p = p->next;
cin >> num;
}
}
void LNode::DestroyList() {
auto p = this->next;
while (p) {
auto del = p;
p = p->next;
delete del;
}
}
LNode *LNode::Reverse() {
if (!this->next) {
return this;
}
auto res = this->next->Reverse();
this->next->next = this;
this->next = nullptr;
return res;
}
void LNode::Traverse() {
auto p = this->next;
if (!p) {
cout << "List is null" << endl;
return;;
}
while (p) {
printf(" %d", p->data);
p = p->next;
}
printf("\n");
}
void LNode::Delete_X(ElemType X) {
LNode *p = this;
while (p) {
if (p->next->data == X) {
auto del = p->next;
p->next = del->next;
delete del;
//del = nullptr;
}
p = p->next;
}
}
void LNode::Delete_Min() {
if (!this->next) {
return;
} else if (!this->next->next) {
delete this->next;
this->next = nullptr;
return;
}
auto NextIsDel = this;
//auto DelData = NextIsDel->next->data;
auto cur = this;
while (cur->next) {
if (cur->next->data <= NextIsDel->next->data) {
NextIsDel = cur;
}
cur = cur->next;
}
NextIsDel->next = NextIsDel->next->next;
//delete NextIsDel->next;
}
unsigned int LNode::Partition(ElemType A[], unsigned int low, unsigned int high) {
ElemType pivot = A[low];
while (low < high) {
while (low < high && A[high] >= pivot) {
--high;
}
A[low] = A[high];
while (low < high && A[low] <= pivot) {
++low;
}
A[high] = A[low];
}
A[low] = pivot;
return low;
}
void LNode::QuickSort(ElemType A[], unsigned int low, unsigned int high) {
if (low < high) {
unsigned int pivotpos = Partition(A, low, high);
QuickSort(A, low, pivotpos - 1);
QuickSort(A, pivotpos + 1, high);
}
}
void LNode::SortLinkedList() {
if (!this->next || !this->next->next) {
printf("Needn't to be sorted\n");
return;
}
auto p = this->next;
unsigned int TopOfA = 0;
ElemType A[this->GetLength()];
while (p) {
A[TopOfA] = p->data;
TopOfA++;//When the loop breaks, TopOfA is the num of the elems in this linkedList
p = p->next;
}
sort(A, A + TopOfA);
//QuickSort(A, 0, TopOfA);
p = this->next;
auto cur = 0;
while (p) {
p->data = A[cur];
cur++;
p = p->next;
}
}
void LNode::Delete_S_2_E(ElemType Start, ElemType End) {
bool flag = false;
auto BeforeDel = this;
while (BeforeDel->next) {
if ((BeforeDel->next->data >= Start) && (BeforeDel->next->data <= End)) {
printf(" %d", BeforeDel->next->data);
BeforeDel->next = BeforeDel->next->next;
flag = true;
} else {
BeforeDel = BeforeDel->next;
}
}
if (flag) {
printf(", which are in the range of %d to %d has been deleted\n", Start, End);
} else {
printf("No elem is deleted\n");
}
}
unsigned int LNode::GetLength() {
unsigned int count = 0;
auto p = this->next;
while (p) {
count++;
p = p->next;
}
return count;
}
void LNode::FindFirstCommonNode(LNode *L2) {
auto Len1 = this->GetLength();
auto Len2 = L2->GetLength();
if (!Len1 || !Len2) {
printf("No common node\n");
return;
}
auto tmp1 = this->next;
auto tmp2 = L2->next;
while (Len1 != Len2) {
if (Len1 > Len2) {
tmp1 = tmp1->next;
Len1--;
} else {
tmp2 = tmp2->next;
Len2--;
}
}
while (tmp1 && tmp2) {
if (tmp1 == tmp2) {
printf("Common Node found, its addr is %p, its data is %d\n", tmp1, tmp1->data);
return;
}
tmp1 = tmp1->next;
tmp2 = tmp2->next;
}
printf(" Common Node not found\n");
}
LNode *LNode::FindMin() {
if (!this->next) {
return nullptr;
}
auto p = this->next;
auto LocMin = p;
while (p) {
if (p->data <= LocMin->data) {
LocMin = p;
}
p = p->next;
}
return LocMin;
}
void LNode::SortLinkedList_NoTmpSpace() {
auto newHead = new LNode;
LNode *tmp = newHead;
while (this->next) {
auto del = this->FindMin();
auto ins = new LNode(del->data);
tmp->next = ins;
tmp = tmp->next;
this->Delete_Min();
}
this->next = newHead->next;
delete newHead;
}
/*P37.10, P37.11*/
void LNode::Divide_Odd_Even() {
auto A = new LNode;
auto B = new LNode;
auto tmpA = A;
auto tmpB = B;
unsigned int cur = 1;
auto TMP = this->next;
while (TMP) {
if (cur % 2 == 1) {
auto insA = new LNode(TMP->data);
tmpA->next = insA;
tmpA = tmpA->next;
} else {
auto insB = new LNode(TMP->data);
tmpB->next = insB;
tmpB = tmpB->next;
}
cur++;
TMP = TMP->next;
}
printf("TraverseOdd:");
A->Traverse();
A->DestroyList();
printf("TraverseEven:");
B->Traverse();
B->DestroyList();
}
/*P37.12*/
/*I promise you the linkedlist has been sorted*/
void LNode::MakeElemsUnique() {
if (!this->next || !this->next->next) {
return;
}
auto cur_node = this->next;
while (cur_node) {
auto next_node = cur_node;
while (next_node && next_node->data == cur_node->data) {
auto del = next_node;
next_node = next_node->next;
if (del != cur_node) {
delete del;
cur_node->next = next_node;
}
}
cur_node = next_node;
}
}
/*P37.13*/
/*I promise you the linkedlist has been sorted*/
void LNode::Merge2LinkList_Dec(LNode *L2) {
auto newHead = new LNode;
auto tmpHead1 = this->next;
auto tmpHead2 = L2->next;
while (tmpHead1 && tmpHead2) {
if (tmpHead1->data < tmpHead2->data) {
auto ins = tmpHead1;
tmpHead1 = tmpHead1->next;
ins->next = newHead->next;
newHead->next = ins;
} else {
auto ins = tmpHead2;
tmpHead2 = tmpHead2->next;
ins->next = newHead->next;
newHead->next = ins;
}
}
if (tmpHead1) {
while (tmpHead1) {
auto ins = tmpHead1;
tmpHead1 = tmpHead1->next;
ins->next = newHead->next;
newHead->next = ins;
}
}
if (tmpHead2) {
while (tmpHead2) {
auto ins = tmpHead2;
tmpHead2 = tmpHead2->next;
ins->next = newHead->next;
newHead->next = ins;
}
}
this->next = newHead->next;
delete newHead;
}
/*P37.14*/
/*I promise you the linkedlist has been sorted increasingly*/
void LNode::Merge2LinkList_Inc(LNode *L2) {
auto newHead = new LNode;
auto cur = newHead;
auto tmp1 = this->next;
auto tmp2 = L2->next;
while (tmp1 && tmp2) {
if (tmp1->data < tmp2->data) {
auto tmp1_next = tmp1->next;
tmp1->next = nullptr;
cur->next = tmp1;
tmp1 = tmp1_next;
} else {
auto tmp2_next = tmp2->next;
tmp1->next = nullptr;
cur->next = tmp2;
tmp2 = tmp2_next;
}
cur = cur->next;
}
if (!tmp1) {
cur->next = tmp2;
}
if (!tmp2) {
cur->next = tmp1;
}
this->next = newHead->next;
delete newHead;
}
/*P37.15*/
/*I promise you the linkedlist has been sorted increasingly*/
void LNode::Get2LinkListsIntersection(LNode *L2) {
auto newHead = new LNode;
auto cur = newHead;
auto tmp1 = this->next;
auto tmp2 = L2->next;
while (tmp1 && tmp2) {
if (tmp1->data == tmp2->data) {
auto tmp1_next = tmp1->next;
tmp1->next = nullptr;
cur->next = tmp1;
tmp1 = tmp1_next;
tmp2 = tmp2->next;
cur = cur->next;
} else if (tmp1->data < tmp2->data) {
auto del = tmp1;
tmp1 = tmp1->next;
delete del;
} else {
auto del = tmp2;
tmp2 = tmp2->next;
delete del;
}
}
this->next = newHead->next;
delete newHead;
}
/*P37.16*/
bool LNode::IsSuccessiveSeq(LNode *B) {
if (!this->next || !B->next) {
return false;
}
auto cur_A = this->next;
while ((cur_A->data != B->next->data) && cur_A) {
cur_A = cur_A->next;
}
if (!cur_A) {
return false;
} else {
auto cur_B = B->next;
while (cur_A && cur_B) {
if (cur_A->data != cur_B->data) {
return false;
}
cur_A = cur_A->next;
cur_B = cur_B->next;
}
if (!cur_A && cur_B) {
return false;
}
}
return true;
}
/*P37.21【2009】*/
bool LNode::FindReverseKthElem(unsigned int K) {
auto p = this;
auto copy_K = K;
while (K-- && p) {
p = p->next;
}
if (!p) {
return false;
} else {
auto rear = this;
while (p) {
rear = rear->next;
p = p->next;
}
cout << " Reversed " << copy_K << "th elem is " << rear->data << endl;
}
return true;
}
void LNode::MakeElemsUniqueAbs(unsigned int dataRange) {
if (!this->next || !dataRange) {
return;
}
bool *Hash = new bool[dataRange + 1]; //TODO:数据绝对值范围小于等于n,需要开辟n+1个数组空间
for (unsigned int i = 0; i < dataRange + 1; i++) {
Hash[i] = false;
}
auto newHead = new LNode;
auto cur = newHead;
auto p = this->next;
while (p) {
if (!Hash[abs(p->data)]) {
Hash[abs(p->data)] = true;
auto ins = new LNode(p->data);
cur->next = ins;
cur = ins;
}
p = p->next;
}
this->next = newHead->next;
delete[]Hash;
delete newHead;
}
void Sln3() {
cout << "P37.3: Reverse traverse:" << endl;
auto L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->next = L1->next->Reverse();
L1->Traverse();
}
void Sln4() {
cout << "P37.4: Delete min:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->Delete_Min();
L1->Traverse();
}
void Sln5() {
cout << "P37.5: Reverse directly:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->next = L1->next->Reverse();
L1->Traverse();
}
void Sln6() {
cout << "P37.6: Sort increasingly:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->SortLinkedList();
L1->Traverse();
}
void Sln7() {
cout << "P37.7: Delete elems in range:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
ElemType Start, End;
cout << "Start: ";
cin >> Start;
cout << "End: ";
cin >> End;
cout << "P37.7: Delete elems from :" << Start << " to " << End << ":" << endl;
cout << __FUNCTION__ << ":";
L1->Delete_S_2_E(Start, End);
L1->Traverse();
}
void Sln8() {
cout << "P37.8: FindFirstCommonNode:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
LNode *L2 = new LNode;
Create(L2);
auto p = L2;
while (p->next) {
p = p->next;
}
p->next = L1->next->next->next->next->next->next;
cout << __FUNCTION__ << ":";
L1->FindFirstCommonNode(L2);
L1->Traverse();
}
void Sln9() {
cout << "P37.9: SortLinkedList_NoTmpSpace:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
L1->SortLinkedList_NoTmpSpace();
cout << __FUNCTION__ << ":";
L1->Traverse();
}
void Sln10() {
cout << "P37.10: Divide_Odd_Even:" << endl;
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->Divide_Odd_Even();
}
void Sln12() {
cout << "P37.12: MakeElemsUnique:" << endl;
cout << "Create a increasing list: ";
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->MakeElemsUnique();
L1->Traverse();
}
void Sln13() {
cout << "P37.13: Merge2LinkList_Dec:" << endl;
cout << "Create the first increasing lists: ";
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << "Create the second increasing lists: ";
LNode *L2 = new LNode;
Create(L2);
cout << "Successfully create:";
L2->Traverse();
cout << __FUNCTION__ << ":";
L1->Merge2LinkList_Dec(L2);
L1->Traverse();
}
void Sln15() {
cout << "P37.15: Get2LinkListsIntersection:" << endl;
cout << "Create the first increasing lists: ";
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << "Create the second increasing lists: ";
LNode *L2 = new LNode;
Create(L2);
cout << "Successfully create:";
L2->Traverse();
cout << __FUNCTION__ << ":";
L1->Get2LinkListsIntersection(L2);
L1->Traverse();
}
void Sln16() {
cout << "P37.16: IsSuccessiveSeq:" << endl;
cout << "Create the first lists: ";
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << "Create the lists: ";
LNode *L2 = new LNode;
Create(L2);
cout << "Successfully create:";
L2->Traverse();
cout << __FUNCTION__ << ":";
cout << L1->IsSuccessiveSeq(L2) << endl;
L1->Traverse();
}
void Sln21() {
cout << "P37.21: FindReverseKthElem:" << endl;
cout << "Create the lists: ";
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << "K: ";
unsigned int K;
cin >> K;
cout << __FUNCTION__ << ":";
if (!(L1->FindReverseKthElem(K))) {
cout << K << " is out of range" << endl;
}
}
void Sln23() {
cout << "P37.23: MakeElemsUniqueAbs:" << endl;
cout << "Create the lists: ";
LNode *L1 = new LNode;
Create(L1);
cout << "Successfully create:";
L1->Traverse();
cout << __FUNCTION__ << ":";
L1->MakeElemsUniqueAbs(100);
L1->Traverse();
}
int main() {
Sln3();
Sln4();
Sln5();
Sln6();
Sln7();
Sln8();
Sln9();
Sln10();
Sln12();
Sln13();
Sln15();
Sln16();
Sln21();
Sln23();
return 0;
}
测试数据和输出
P37.3: Reverse traverse:
1 2 3 4 5 -1
Successfully create: 1 2 3 4 5
Sln3: 5 4 3 2 1
P37.4: Delete min:
9 5 1 7 8 6 2 0 3 4 -1
Successfully create: 9 5 1 7 8 6 2 0 3 4
Sln4: 9 5 1 7 8 6 2 3 4
P37.5: Reverse directly:
1 2 3 4 -1
Successfully create: 1 2 3 4
Sln5: 4 3 2 1
P37.6: Sort increasingly:
9 5 1 7 8 4 6 3 2 0 -1
Successfully create: 9 5 1 7 8 4 6 3 2 0
Sln6: 0 1 2 3 4 5 6 7 8 9
P37.7: Delete elems in range:
1 2 3 4 5 6 7 8 9 -1
Successfully create: 1 2 3 4 5 6 7 8 9
Start:-10
End:10
P37.7: Delete elems from :-10 to 10:
Sln7: 1 2 3 4 5 6 7 8 9, which are in the range of -10 to 10 has been deleted
List is null
P37.8: FindFirstCommonNode:
1 2 3 4 5 6 7 8 9 -1
Successfully create: 1 2 3 4 5 6 7 8 9
1 2 3 -1
Sln8:Common Node found, its addr is 00000000007b6770, its data is 6
1 2 3 4 5 6 7 8 9
P37.9: SortLinkedList_NoTmpSpace:
2 3
-1
Successfully create: 2 3
Sln9: 2 3
P37.10: Divide_Odd_Even:
1 2 3 4 5 6 7 8 9 10 -1
Successfully create: 1 2 3 4 5 6 7 8 9 10
Sln10:TraverseOdd: 1 3 5 7 9
TraverseEven: 2 4 6 8 10
P37.12: MakeElemsUnique:
Create a increasing list:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 3 3 10 -1
Successfully create: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 3 3 10
Sln12: 1 2 3 10
P37.13: Merge2LinkList_Dec:
Create the first increasing lists:1 2 3 4 5 -1
Successfully create: 1 2 3 4 5
Create the second increasing lists:1 2 3 4 5 -1
Successfully create: 1 2 3 4 5
Sln13: 5 5 4 4 3 3 2 2 1 1
P37.15: Get2LinkListsIntersection:
Create the first increasing lists:1 2 3 4 5 6 7 8 -1
Successfully create: 1 2 3 4 5 6 78
Create the second increasing lists:4 5 6 10 -1
Successfully create: 4 5 6 10
Sln15: 4 5 6
P37.16: IsSuccessiveSeq:
Create the first lists:1 2 3 4 5 6 7 8 9 -1
Successfully create: 1 2 3 4 5 6 7 8 9
Create the lists:2 3 4 -1
Successfully create: 2 3 4
Sln16:1
1 2 3 4 5 6 7 8 9
P37.21: FindReverseKthElem:
Create the lists:1 2 3 4 5 6 -1
Successfully create: 1 2 3 4 5 6
K:5
Sln21: Reversed 5th elem is 2
P37.23: MakeElemsUniqueAbs:
Create the lists:-9 -8 -7 -6 -5 -4 -3 -2 0 1 2 3 4 5 6 7 8 9 10 -1
Successfully create: -9 -8 -7 -6 -5 -4 -3 -2 0 1 2 3 4 5 6 7 8 9 10
Sln23: -9 -8 -7 -6 -5 -4 -3 -2 0 1 10
进程已结束,退出代码 0