#include "pch.h"
#include "iostream"
#include "stdio.h"
#include "queue"
#include "math.h"
#include "stack"
#include "string"
using namespace std;
#define ElemType int
#define VOID -999999
/*
单链表特点:
它是一种动态的储存结构,链表中每个节点占用的储存空间不是预先分配的,而是运行时系统根据需求生成的
*/
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
/*
双链表
*/
typedef struct DLNode {
ElemType data;
struct DLNode *prior, *next;
int Freq = 0;
}DLNode, *Double_LinkList;
/*
循环双链表
*/
typedef struct CDLNode {
ElemType data;
struct CDLNode *prior,*next;
}CDLNode,*Circular_Double_LinkList;
struct Result
{
LinkList head;
LNode* tail;
};
//结点定义
/*
创建空双链表(仅有头节点)
*/
void Double_LinkList_VoidHeadCreate(Double_LinkList &L) {
DLNode s, *p = NULL; int x;
L = new DLNode;
p = L;
L->data = VOID;
L->next = NULL;
L->prior = NULL;
}
/*
双链表头插法
*/
void Double_LinkList_HeadInsert(Double_LinkList &L, ElemType e) {
DLNode *s;
s = new DLNode;
s->data = e;
s->next = L->next;
if(L->next!=NULL)
L->next->prior = s;
L->next = s;
s->prior = L;
}
/*
创建空循环双链表(仅有头节点)
*/
void Circular_Double_LinkList_VoidHeadCreate(Circular_Double_LinkList &L) {
CDLNode s,*p = NULL; int x;
L = new CDLNode;
p = L;
L->data = VOID;
L->next = L;
L->prior = L;
}
/*
循环双链表头插法
*/
void Circular_Double_LinkList_HeadInsert(Circular_Double_LinkList &L, ElemType e) {
CDLNode *s;
s = new CDLNode;
s->data = e;
s->next = L->next;
L->next->prior = s;
L->next = s;
s->prior = L;
}
/*
循环双链表尾插法
*/
void Circular_Double_LinkList_TailInsert(Circular_Double_LinkList &L, ElemType e) {
CDLNode *s;
s = new CDLNode;
s->data = e;
s->prior = L->prior;
L->prior->next = s;
L->prior = s;
s->next = L;
}
/*
创建循环单链表(仅有头节点)
*/
void Circular_List_VoidHeadCreate(LinkList &L, LNode *&tail) {
struct LNode s; int x;
L = new LNode;;
L->data = VOID;
L->next = L;
tail = L;
}
/*
循环头插法
*/
void Circular_List_HeadInsert(LinkList &L, ElemType e, LNode *&tail) {
LNode *s;
s = new LNode;;
s->data = e;
if (L->data == VOID) {
if (tail == L) {
tail = s;
}
s->next = L->next;
L->next = s;
}
else {
s->next = L;
L = s;
}
}
/*
创建空单链表(仅有头节点)
*/
void List_VoidHeadCreate(LinkList &L, LNode *&tail) {
struct LNode s; int x;
L = new LNode;;
L->data = VOID;
L->next = NULL;
tail = L;
}
/*
头插创表法
*/
void List_HeadCreate(LinkList &L,LNode *&tail) {
LNode *s; int x;
bool tailCatch = true;
L = new LNode;
L->data = VOID;
L->next = NULL;
cin >> x;
while (x != 9999) {
s = new LNode;
if (tailCatch) {
tail = s;
tailCatch = false;
}
s->data = x;
s->next = L->next;
L->next = s;
cin >> x;
}
}
/*
无头节点头插创表法
*/
void List_HeadlessCreate(LinkList &L, LNode *&tail) {
LNode *s; int x;
bool tailCatch = true;
cin >> x;
if (x == 9999)
return;
L = new LNode;
L->data = x;
L->next = NULL;
cin >> x;
while (x != 9999) {
s = new LNode;
if (tailCatch) {
tail = s;
tailCatch = false;
}
s->data = x;
s->next = L;
L = s;
cin >> x;
}
}
/*
无头节点头插创表法,仅初始化
*/
void List_HeadlessCreate_NoInput(LinkList &L, LNode *&tail,ElemType e) {
if (e == 9999)
return;
L = new LNode;
L->data = e;
L->next = NULL;
tail = L;
}
/*
尾插创表法(参数传tail)
*/
Result List_TailCreate(LinkList L, LNode * tail) {
Result ret;
LNode *s, *r = L; int x;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
cin >> x;
while (x != 9999) {
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
cin >> x;
}
r->next = NULL;
tail = r;
ret.head = L;
ret.tail = tail;
return ret;
}
/*
按序号获取元素
*/
LNode* GetElem(LinkList L, int i) {
int j = 1;
LNode *p = L->next;
if (i == 0)
return L;
if (i < 1)
return NULL;
while (p&&j < i) {
p = p->next;
j++;
}
return p;
}
/*
根据值查找元素
*/
LNode* LocateElem(LinkList L, ElemType e) {
LNode *p = L->next;
while (p != NULL && p->data != e) {
p = p->next;
}
return p;
}
/*
头插法
*/
void List_HeadInsert(LinkList &L, ElemType e, LNode *&tail) {
LNode *s;
s = new LNode;;
s->data = e;
if(L->data == VOID){
if (tail == L) {
tail = s;
}
s->next = L->next;
L->next = s;
}
else {
s->next = L;
L = s;
}
}
/*
尾插法
*/
void List_TailInsert(ElemType e, LNode *&tail) {
LNode *s;
s = new LNode;;
s->data = e;
tail->next = s;
tail = s;
tail->next = NULL;
}
/*
打印单链表
*/
void PrintList(LinkList L) {
if (L == NULL)
return;
LNode* p = L->next; int count = 0;
cout << ("单链表数据为:");
if (L->data != VOID) {//如果无头节点
cout << "[" << count++ << "]" << L->data << " " ;
}
while (p != NULL) {
cout << "[" << count++ << "]" << p->data << " ";
p = p->next;
}
cout << endl;
}
/*
打印双链表
*/
void PrintList(Double_LinkList &L) {
if (L == NULL)
return;
DLNode* p = L->next; int count = 0;
cout << ("单链表数据为:");
if (L->data != VOID) {//如果无头节点
cout << "[" << count++ << "]" << L->data << " ";
}
while (p != NULL) {
cout << "[" << count++ << "]" << p->data << " ";
p = p->next;
}
cout << endl;
}
/*
打印循环双链表
*/
void PrintList(Circular_Double_LinkList &L) {
if (L == NULL)
return;
CDLNode* p = L->next; int count = 0;
cout << ("单链表数据为:");
if (L->data != VOID) {//如果无头节点
cout << "[" << count++ << "]" << L->data << " ";
}
while (p!=L) {
cout << "[" << count++ << "]" << p->data << " ";
p = p->next;
}
cout << endl;
}
/*
对链表进行排序,正序s
*/
void SoftList(LinkList &L,LNode *<ail) {
LNode *p = L->next, *pre = NULL;
LNode *r = p->next;
p->next = NULL;
p = r;
while (p != NULL) {
r = p->next;
pre = L;
/*扫描pre的A组,如果P->data < p->data,则将pre往后移扫描下一个,直到发现当前指针的值>=需要插入
的值时,将需要插入的值插入到这个大于插入值的元素之前,如果下一个指针为空,则代表需要插入的值
大于整个A组,将该值插入到末尾*/
while (pre->next != NULL && pre->next->data < p->data)
pre = pre->next;
p->next = pre->next; //插入到pre与pre->next之间(pre->next==NULL时,插入到最后一个)
pre->next = p;
p = r;
}
LTail = pre;
}
/*
清空双链表,仅留头节点
*/
void ClearList(Double_LinkList &L) {
DLNode *p = L->next, *r;
while (p != NULL) {
r = p->next;
free(p);
p = r;
}
L->data = VOID;
L->next = NULL;
L->prior = NULL;
}
/*
清空循环双链表,仅留头节点
*/
void ClearList(Circular_Double_LinkList &L) {
CDLNode *p = L->next, *r;
while (p != L) {
r = p->next;
free(p);
p = r;
}
L->data = VOID;
L->next = L;
L->prior = L;
}
/*
清空链表,仅留头节点
*/
void ClearList(LinkList &L, LNode *<ail) {
LNode *p = L->next,*r;
while (p != NULL) {
r = p->next;
free(p);
p = r;
}
L->data = VOID;
L->next = NULL;
LTail = L;
}
/*
反回单链表长度
*/
int GetLength(LinkList &L) {
int count = 0;
LNode* p = L;
while (p->next != NULL) {
count++;
p = p->next;
}
return count;
}
/*
递归删除不带头节点的单链表L中所有X的节点
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_3_1(LinkList &L,ElemType x) {
LNode* p;
if (L == NULL)
return;
if (L->data == x) {
p = L;
L = L->next; //此处L是引用,所以改变L的值,会改变原L的前驱的next的值
free(p);
Mos_2_3_1(L, x);
}
else
Mos_2_3_1(L->next, x);
}
/*
递归删除带头节点的单链表L中所有X的节点
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_3_2(LinkList &L, ElemType x) {
LNode* p;
if (L == NULL)
return;
if (L->data == VOID) //跳过头节点
Mos_2_3_2(L->next, x);
if (L->data == x) {
p = L;
L = L->next;
free(p);
Mos_2_3_2(L, x);
}else
Mos_2_3_2(L->next, x);
}
/*
反向输出带头节点的单链表L
算法思想:
利用递归思想,先获取到最后一个节点进行输出
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_3_3(LinkList &L) {
if (L->data == VOID) //头节点位置做前置输出,可省略
cout << "该链表数据逆置后为:";
if (L == NULL)
return;
if (L->next != NULL)
Mos_2_3_3(L->next); //先递归
if (L->data != VOID)
cout << L->data << " "; //再输出
else //头节点位置做后置输出,可省略
cout << endl;
}
/*
找到带头节点单链表L中最小的节点,并删除
算法思想:
用一个指针纪录最小的节点,在扫描结束后删除该节点
注这个指针最好是纪录最小节点的前一个节点,方便在扫描后直接删除
*/
void Mos_2_3_4(LinkList &L) {
LNode* p = L,*q = L->next,*n;
while (p->next != NULL) {
if (p->next->data < q->next->data) {
q = p;
}
p = p->next;
}
n = q->next;
q->next = q->next->next;
free(n);
}
/*
将带头节点的单链表L逆置
算法思想:
用指针纪录前一个元素与后一个元素,然后使自己的next等于前一个元素,然后到下一个元素重复该过程,
直到当前元素为空,代表已经全部逆置,将头节点指向当前元素(原本的最后一个元素)
注:第一个元素的前置为NULL
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_3_5(LinkList &L,LNode *&tail/*该部分用于保存尾指针,可去掉*/) {
if (!L->next)
return;
LNode* p = L->next,*q,*r = NULL;
tail = p;/*该部分用于保存尾指针,可去掉*/
while (p != NULL) {
q = p->next;
p->next = r;
r = p;
p = q;
}
L->next = r;
}
/*
使一个带头节点的单链表L递增有序
算法思路:
1、将原链表分成两个链表(充分利用空间),使头节点的下一指针为NULL作A链表
2、扫描剩下的B链表(外循环),利用指针Pre将B链表的第一个元素依次与A链表中的元素比较,进入内循环
3、比较结果分三种情况
(1)、如果该元素小于A链表的值(pre->next),则使指针向后跳,比较下一个元素
(2)、如果该元素大于等于A链表的值,则代表找到了插入的位置,跳出内循环
到A链表对应位置中
(3)、如果A链表空了(即pre->next==NULL)代表该值在A链表中为最大的值,跳出内循环
4、跳出内循环后,将B链表的第一个值插入到对应位置,将B链表的头指针往后跳
5、判断B链表是否为空,若为空,则跳出外循环,若不为空,则继续插入
时间复杂度O(n^2) 空间复杂度O(1)
*/
void Mos_2_3_6(LinkList &L) {
LNode *p = L->next, *pre;
LNode *r = p->next;
p->next = NULL;
p = r;
while (p != NULL) {
r = p->next;
pre = L;
/*扫描pre的A组,如果P->data < p->data,则将pre往后移扫描下一个,直到发现当前指针的值>=需要插入
的值时,将需要插入的值插入到这个大于插入值的元素之前,如果下一个指针为空,则代表需要插入的值
大于整个A组,将该值插入到末尾*/
while (pre->next != NULL && pre->next->data < p->data)
pre = pre->next;
p->next = pre->next; //插入到pre与pre->next之间(pre->next==NULL时,插入到最后一个)
pre->next = p;
p = r;
}
}
/*
部分修改
*/
void Mos_2_3_6_1(LinkList &L) {
LNode *p = L->next,*pre,*r;
L->next = NULL;
while (p != NULL) {
r = p->next;
pre = L;
/*扫描pre的A组,如果P->data < p->data,则将pre往后移扫描下一个,直到发现当前指针的值>=需要插入
的值时,将需要插入的值插入到这个大于插入值的元素之前,如果下一个指针为空,则代表需要插入的值
大于整个A组,将该值插入到末尾*/
while (pre->next != NULL && pre->next->data < p->data) {
pre = pre->next;
}
p->next = pre->next; //插入到pre与pre->next之间(pre->next==NULL时,插入到最后一个)
pre->next = p;
p = r;
}
}
/*
删除带头节点的单链表中值在left与right范围内的元素
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_3_7(LinkList &L, ElemType left, ElemType right,LNode *&tail/*该部分用于保存尾指针,可去掉*/) {
LNode* r, *p = L->next,*q = L;
while (p->next != NULL) {
r = p->next;
if (p->data > left&&p->data < right) {
q->next = r;
free(p);
}
else {
q = q->next;
}
p = r;
}
tail = p;/*该部分用于保存尾指针,可去掉*/
}
/*
将BL的第BLoc(从0开始)元素的next变为AL的第ALoc元素的next
即将AL的第ALoc以后的元素拼接到BL的BLoc之后,为2-3-8题做准备
时间复杂度O(ALoc+BLoc) 空间复杂度O(1)
*/
bool Mos_2_3_8_1(LinkList &AL, LinkList &BL,int ALoc,int BLoc) {
LNode *ap = AL, *bp =BL;
for (int i = 0; i < ALoc; i++) {
if (ap->next != NULL)
ap = ap->next;
else
return false;
}
for (int i = 0; i < BLoc; i++) {
if (bp->next != NULL)
bp = bp->next;
else
return false;
}
bp->next = ap->next;
}
/*
找出AL与BL相同的第一个节点(地址相同)
算法思想:
由于如果AL与BL如果有节点相同,则后继节点皆相同,且相同节点的长度相同,所以
len(AL)= len(AL不同节点)+len(相同节点)
len(BL)= len(BL不同节点)+len(相同节点)
若len(AL)>len(BL),则代表len(AL不同节点)>len(BL不同节点),且len(AL)-len(BL)=len(AL不同节点)-len(BL不同节点),
BL同理,所以先让len更大的链表先向后推abs(len(AL)-len(BL))个,则len(长的链表所剩不同节点)=len(短的链表不同节点)
同时向后推,找到第一个相同节点,则为AL与BL的共同节点
时间复杂度O(len(AL)+len(BL))(需要算出AL与BL长度) 空间复杂度O(1)
*/
LNode* Mos_2_3_8(LinkList &AL, LinkList &BL) {
int len1 = GetLength(AL), len2 = GetLength(BL);
LNode *p1 =AL, *p2 = BL;
if (len1 < len2) {
for (int i = 0; i < len2 - len1; i++) {
p2 = p2->next;
}
}
else {
for (int i = 0; i < len1 - len2; i++) {
p1 = p1->next;
}
}
for (int i = 0; i < abs(len1 - len2); i++) {
if (p1->next == p2->next) {
return p1->next;
}
p1 = p1->next;
p2 = p2->next;
}
return NULL;
}
/*
按次序输出L中的元素,并释放节点的空间
算法思想:
双重遍历输出,并释放
时间复杂度O(n^2) 空间复杂度O(1)
*/
void Mos_2_2_9(LinkList &L) {
LNode *p = L->next, *pre = L;
cout << "按顺序输出L:";
while (L->next != NULL) {
p = L->next;
pre = L;
while (p->next != NULL) {
if (p->next->data < pre->next->data) {
pre = p;
}
p = p->next;
}
cout << pre->next->data << " ";
p = pre->next;
pre->next = pre->next->next;
free(p);
}
cout << endl;
}
/*
将一个带头节点的A单链表拆分成A B两表,A存放序号为奇数的元素,B存放序号为偶数的元素
算法思想:
四个指针一个代表分类后的A一个代表分类后的B,一个代表当前扫描位置,一个保存下一个位置
结束循环后要p->next =NULL,q->next = NULL,将A B的末尾断链
时间复杂度O(len(AL)) 空间复杂度O(1)
*/
void Mos_2_2_10(LinkList &AL, LNode *&ALTail, LinkList &BL, LNode *&BLTail) {
LNode *p = AL, *q = BL,*r,*s = AL->next;
int count = 0;
while (s != NULL) {
if (s->next != NULL)
r = s->next;
else
r = NULL;
if (count++ % 2 == 0) {
q->next = s;
q = q->next;
}
else {
p->next = s;
p = p->next;
}
s = r;
}
p->next = NULL;
q->next = NULL;
ALTail = p;
BLTail = q;
}
/*
将AL分成两个链表,其中偶数位归于AL,奇数位置归于BL,但是BL需要逆置
算法思想:
与10题类似,仅在插入BL时倒着插
在结尾时,让BL->next = q,最后一位为第一位
时间复杂度O(len(AL)) 空间复杂度O(1)
*/
void Mos_2_2_11(LinkList &AL, LNode *&ALTail, LinkList &BL) {
LNode *p = AL, *q = NULL, *r, *s = AL->next;
int count = 0;
while (s != NULL) {
r = s->next;
if (count++ % 2 == 0) {
p->next = s;
p = p->next;
}
else {
s->next = q;
q = s;
}
s = r;
}
p->next = NULL;
BL->next = q;
ALTail = p;
}
/*
对一个有序链表去重
算法思想:
对比当前指针数据和下一个指针数据是否相同,相同则p->next = 下一个指针的next,并释放下一个指针
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_2_12(LinkList &L, LNode *<ail) {
LNode *p = L,*pre;
while (p->next!=NULL) {
if(p->next->data == p->data){
pre = p->next;
p->next = pre->next;
free(pre);
}
else {
p = p->next;
}
}
LTail = p;
}
/*
将有序链表AL与BL,按从大到小的顺序放回AL
算法思想:
一个指针指向新AL,一个指向AL的扫描值,一个指向BL的扫描值,
如果BL的扫描值不为空,且AL扫描值为空,或者AL的值大于BL的值,则反向将BL的节点指向新AL的最后一个节点,
注意保存下一个扫描值,反之亦然
当AL与BL都为空时跳出
时间复杂度O(len(AL)+Len(BL)) 空间复杂度O(1)
*/
void Mos_2_2_13(LinkList &AL, LinkList &BL) {
LNode *p = AL->next, *q = BL->next,*s = NULL,*r = NULL;
while (p != NULL || q != NULL) {
if (q != NULL && (p == NULL || p->data > q->data)) {
r = q->next;
q->next = s;
s = q;
q = r;
}
if (p != NULL && (q == NULL || q->data >= p->data)) {
r = p->next;
p->next = s;
s = p;
p = r;
}
}
AL->next = s;
}
/*
将两个递增有序链表A与B中的公共元素提出新建到C表
算法思想:
不停滚动AL与BL的扫描指针,发现相同置入C表
时间复杂度O(len(AL)+len(BL)) 空间复杂度(len(AL)+len(BL))(需要新建一个表接AL与BL的结果)
*/
void Mos_2_2_14(LinkList &AL, LinkList &BL,LinkList &CL,LNode *&CLTail) {
CL = new LNode;
CL->data = VOID;
LNode *p = AL->next, *q = BL->next, *r = CL;
while(p!=NULL&&q!=NULL){
if (p->data == q->data) {
r->next = new LNode;
r->next->data = p->data;
r = r->next;
p = p->next;
q = q->next;
}
else {
if (p->data < q->data) {
p = p-> next;
}
else {
q = q-> next;
}
}
}
r->next = NULL;
CLTail = r;
}
/*
求A与B链表的交集(对应位置相同的元素)放回A
算法思想:
依次扫描,并放回A,同时清除A链表不是交集的节点
时间复杂度O(len(AL)+len(BL)) 空间复杂度(1)
*/
void Mos_2_2_15(LinkList &AL, LNode *&aLTail, LinkList &BL) {
LNode *p = AL->next, *q = BL->next,*r = NULL,*s = AL;
while (p != NULL && q != NULL) {
r = p->next;
if (p->data == q->data) {
s->next = p;
s = s->next;
}
else {
free(p);
}
p = r;
q = q->next;
}
s->next = NULL;
aLTail = s;
while (p != NULL) {
r = p->next;
free(p);
p = r;
}
}
/*
判断BL是不是AL的连续子序列
算法思想:
双循环,外部纪录AL的指针,然后每次内循环结束pre = pre->next
内循环判断BL的指针q是否为空,不是则比较下一个p和q,若q为空代表时连续子序列
当pre为空时,代表没有连续子序列
时间复杂度O(len(AL)*len(BL)) 空间复杂度O(1)
*/
bool Mos_2_2_16(LinkList &AL, LinkList &BL) {
LNode *p = AL->next, *q = BL->next,*pre = AL->next;
bool b = true;
while (pre != NULL ) {
p = pre;
q = BL->next;
b = true;
while (q != NULL) {
if (p == NULL) {
b = false;
break;
}
if (p->data != q->data){
b = false;
break;
}
p = p->next;
q = q->next;
}
if (b) {
return true;
}
else {
pre = pre->next;
}
}
return false;
}
/*
判断循环双链表CL是否对称
算法思想:
两个指针分别从头尾(除开头指针)出发(方向相反),如果头不等于尾则代表该位置不对称,一直找到两个指针相等或者
从头出发的指针的下一个等于从尾出发的指针为止
时间复杂度O(n) 空间复杂度O(1)
*/
bool Mos_2_2_17(CDLNode *&CL) {
CDLNode *p = CL->next,*q = CL->prior;
if (p == CL)
return false;
while (p != q ) {
if (p->data != q->data) {
return false;
}
if (p->next == q)
return true;
p = p->next;
q = q->prior;
}
return true;
}
/*
将BL拼接到AL上
*/
void Mos_2_2_18(CDLNode *&CAL, CDLNode *&CBL) {
CBL->prior->next = CAL;
CAL->prior->next = CBL->next;
CBL->next->prior = CAL->prior;
CAL->prior = CBL->prior;
CBL->next = CBL;
CBL->prior = CBL;
}
/*
按顺序输出循环双链表的元素,输出后删除
时间复杂度O(n) 空间复杂度O(1)
*/
void Mos_2_2_19(CDLNode *&CL) {
CDLNode *p = CL->next, *min = p,*r=NULL,*leftMin = NULL;
int count = 0;
cout << "按大小顺序输出CL:";
while (CL->next != CL) {
p = CL->next;
min = p;
leftMin = CL;
while (p != CL) {
if (min->data > p->data) {
min = p;
leftMin = r;
}
r = p;
p = p->next;
}
cout << "[" << count++ << "]" << min->data << " ";
leftMin->next = min->next;
min->next->prior = leftMin;
free(min);
}
free(CL);
}
void Mos_2_2_20(DLNode *&DL,ElemType x) {
DLNode *p = DL->next,*r;
while (p != NULL) {
r = p->next;
if (p->data == x) {
p->Freq += 1;
DLNode *q = p->prior;
while (q != DL) {
if (q->Freq <= p->Freq) {
q->prior->next = p;
p->next->prior = q;
q->next = p->next;
p->prior = q->prior;
p->next = q;
q->prior = p;
q = p->prior;
}
else {
break;
}
}
}
p = r;
}
}
/*
输出L的倒数第k个元素,若有返回1,无返回0
算法思想:
设有p与q两个指针,p自头向尾遍历,当p=尾指针的NULL时,可知倒数第k个指针与p之间的距离为k
于是,当p指向第k个元素(正着数)时,令q同步自头向尾遍历,当p指向尾指针的NULL时,q刚好指向倒数第k个指针
时间复杂度O(n) 空间复杂度O(1)
*/
int Mos_2_2_21(LNode *&L, int k) {
int count = 1;
LNode *p = L->next, *q=L;
while (p != NULL) {
if (count < k) {
count++;
}
else {
q = q->next;
}
p = p->next;
}
if (count < k) {
return 0;
}
else {
cout << "倒数第" << k << "个元素为" << q->data << endl;
return 1;
}
}
/*
找出A链表与B链表的第一个共同元素
算法设计:
同2-3-8算法
时间复杂度O(Max(len(AL),len(BL)) 空间复杂度O(1)
*/
LNode* Mos_2_2_22(LNode *&AL, LNode *&BL) {
LNode *p = AL->next, *q = BL->next;
int len1 = GetLength(AL), len2 = GetLength(BL),count = 0;
if (len1 < len2) {
for (int i = 0; i < len2 - len1; i++) {
q = q->next;
}
}
else {
for (int i = 0; i < len1 - len2; i++) {
p = p->next;
}
}
while (p != NULL) {
if (p->data == q->data) {
return p;
}
p = p->next;
q = q->next;
count++;
}
return NULL;
}
/*
删除L的所有绝对值重复的元素
算法设计:
利用空间换时间,用数组来判断这个链表元素是否出现过,出现则删除
空间复杂度O(n) 空间复杂度O(n)
*/
void Mos_2_2_23(LNode *&L,int n) {
ElemType *integer = new int[n+1];
for (int i = 0; i < n + 1; i++) {
integer[i] = 0;
}
LNode *p = L->next,*pre = L,*r;
while (p != NULL) {
r = p->next;
if (integer[abs(p->data)] == 0) {
integer[abs(p->data)]++;
pre = p;
}
else {
pre->next = p->next;
free(p);
}
p = r;
}
}
int main() {
LinkList AL = NULL;
LNode* ALTail = NULL;
LinkList BL = NULL;
LNode* BLTail = NULL;
LinkList CL = NULL;
LNode* CLTail = NULL;
LinkList DL = NULL;
LNode* DLTail = NULL;
LinkList EL = NULL;
LNode* ELTail = NULL;
Circular_Double_LinkList CAL = NULL;
Circular_Double_LinkList CBL = NULL;
Double_LinkList DAL = NULL;
Circular_Double_LinkList_VoidHeadCreate(CAL);
Circular_Double_LinkList_VoidHeadCreate(CBL);
Double_LinkList_VoidHeadCreate(DAL);
//List_HeadCreate(BL, BLTail);
List_VoidHeadCreate(BL, BLTail);
//List_VoidHeadCreate(EL, ELTail);
List_HeadlessCreate_NoInput(AL, ALTail,3);
//PrintList(l);
for (int i = 2; i < 4; i++) {
List_HeadInsert(AL, i, ALTail);
List_HeadInsert(BL, i, BLTail);
}
for (int i = 2; i < 4; i++) {
List_TailInsert(i, ALTail);
List_TailInsert(i, BLTail);
}
/* 练习题2-3-1 */
//cout << endl << "练习题2-3-1" << endl;
//PrintList(AL);
//Mos_2_3_1(AL, 3);//会丢失尾指针 影响后续结果 使用时去掉注释
//PrintList(AL);
//cout << endl;
/* 练习题2-3-2 */
//cout << endl << "练习题2-3-2" << endl;
//PrintList(BL);
//Mos_2_3_2(BL, 3);//会丢失尾指针 影响后续结果 使用时去掉注释
//PrintList(BL);
//cout << endl;
/* 练习题2-3-3 */
cout << endl << "练习题2-3-3" << endl;
for (int i = 2; i < 4; i++) {
List_TailInsert(i, BLTail);
}
List_TailInsert(1, BLTail);
PrintList(BL);
Mos_2_3_3(BL);
cout << endl;
/* 练习题2-3-4 */
//cout << endl << "练习题2-3-4"<< endl;
//for (int i = 2; i < 4; i++) {
// List_TailInsert(i, BLTail);
//}
//PrintList(BL);
//Mos_2_3_4(BL);//会丢失尾指针 影响后续结果 使用时去掉注释
//PrintList(BL);
//cout << endl;
/* 练习题2-3-5 */
cout << endl << "练习题2-3-5" << endl;
for (int i = 4; i < 7; i++) {
List_TailInsert(i, BLTail);
}
PrintList(BL);
Mos_2_3_5(BL,BLTail);
PrintList(BL);
cout << endl;
/* 练习题2-3-6 */
//cout << endl << "练习题2-3-6" << endl;
//PrintList(BL);
//Mos_2_3_6_1(BL);//会丢失尾指针 影响后续结果 使用时去掉注释
//PrintList(BL);
//cout << endl;
/* 练习题2-3-7 */
cout << endl << "练习题2-3-7" << endl;
PrintList(BL);
Mos_2_3_7(BL, 2, 4, BLTail);
PrintList(BL);
cout << endl;
/* 练习题2-3-8 */
cout << endl << "练习题2-3-8" << endl;
List_VoidHeadCreate(CL, CLTail);
for (int i = 2; i < 4; i++) {
List_HeadInsert(CL, i, CLTail);
}
cout << "BL,CL拼接前:" << endl;
PrintList(BL);
PrintList(CL);
cout << "BL,CL拼接后:" << endl;
Mos_2_3_8_1(BL, CL, 3, 1);//会丢失CL的尾指针 影响后续结果 后续使用CL时加上注释
PrintList(BL);
PrintList(CL);
LNode *mos_2_3_8_var = Mos_2_3_8(BL, CL);
if (mos_2_3_8_var != NULL)
cout << "第一个相同的节点为:地址{" << mos_2_3_8_var << "} 值{" << mos_2_3_8_var->data << "}" << endl;
else
cout << "没有相同的节点" << endl;
cout << endl;
/* 练习题2-3-9 */
//cout << endl << "练习题2-3-9" << endl;
//Mos_2_2_9(CL);//会清空CL 若2-2-8开启,会同时清空BL后续 影响后续结果 后续使用BL与CL时加上注释
//cout << endl;
/* 练习题2-3-10 */
cout << endl << "练习题2-3-10" << endl;
PrintList(BL);
PrintList(CL);
Mos_2_2_10(BL, BLTail, CL, CLTail);//会重新添加上CL的尾指针
PrintList(BL);
PrintList(CL);
cout << endl;
/* 练习题2-3-11 */
cout << endl << "练习题2-3-11" << endl;
for (int i = 2; i < 6; i++) {
List_HeadInsert(BL, i, BLTail);
}
PrintList(BL);
PrintList(CL);
Mos_2_2_11(BL, BLTail, CL);//会丢失CL的尾指针 影响后续结果 后续使用CL时加上注释
PrintList(BL);
PrintList(CL);
cout << endl;
/* 练习题2-3-12 */
cout << endl << "练习题2-3-12" << endl;
for (int i = 3; i < 9; i++) {
List_HeadInsert(BL, i, BLTail);
}
SoftList(BL, BLTail);//对BL进行排序,做前置工作
PrintList(BL);
Mos_2_2_12(BL, BLTail);
PrintList(BL);
cout << endl;
/* 练习题2-3-13 */
//cout << endl << "练习题2-3-13" << endl;
//for (int i = 3; i < 9; i++) {
// List_HeadInsert(BL, i, BLTail);
// List_HeadInsert(CL, i, BLTail);
//}
//SoftList(BL, BLTail);//对BL进行排序,做前置工作
//SoftList(CL, CLTail);//对CL进行排序,做前置工作
//PrintList(BL);
//PrintList(CL);
//Mos_2_2_13(BL,CL); //会丢失BL与CL的尾指针 影响后续结果 后续使用BL,CL时加上注释
//PrintList(BL);
//cout << endl;
/* 练习题2-3-14 */
cout << endl << "练习题2-3-14" << endl;
for (int i = 3; i < 6; i++) {
List_HeadInsert(BL, i, BLTail);
List_HeadInsert(CL, i, BLTail);
}
SoftList(BL, BLTail);//对BL进行排序,做前置工作
SoftList(CL, CLTail);//对BL进行排序,做前置工作
PrintList(BL);
PrintList(CL);
Mos_2_2_14(BL, CL,EL,ELTail);
PrintList(EL);
cout << endl;
/* 练习题2-3-15 */
//cout << endl << "练习题2-3-15" << endl;
//PrintList(BL);
//PrintList(CL);
//SoftList(BL, BLTail);//对BL进行排序,做前置工作
//SoftList(CL, CLTail);//对BL进行排序,做前置工作
//Mos_2_2_15(BL, BLTail ,CL);//会导致BL与CL元素重叠,使用时取消注释
//PrintList(BL);
//PrintList(CL);
//cout << endl;
/* 练习题2-3-16 */
cout << endl << "练习题2-3-16" << endl;
ClearList(BL, BLTail);
ClearList(CL, ALTail);
for (int i = 1; i < 4; i++) {
List_HeadInsert(BL, i, ALTail);
}
for (int i = 3; i < 6; i++) {
List_HeadInsert(BL, i, ALTail);
List_HeadInsert(CL, i, BLTail);
}
for (int i = 2; i < 4; i++) {
List_HeadInsert(BL, i, BLTail);
}
cout << "BL" << (Mos_2_2_16(BL, CL)?"是":"不是") << "AL的连续子序列。" << endl;
cout << endl;
/* 练习题2-3-17 */
cout << endl << "练习题2-3-17" << endl;
for (int i = 2; i < 7; i++) {
Circular_Double_LinkList_HeadInsert(CAL, i);
Circular_Double_LinkList_TailInsert(CAL, i);
}
/*for (int i = 1; i < 2; i++) {
Circular_Double_LinkList_TailInsert(CAL, i);
}*/
PrintList(CAL);
cout << "CAL" << (Mos_2_2_17(CAL) ? "是" : "不是") << "对称的循环双链表。" << endl;
cout << endl;
/* 练习题2-3-18 */
cout << endl << "练习题2-3-18" << endl;
ClearList(CAL);
ClearList(CBL);
for (int i = 2; i < 7; i++) {
Circular_Double_LinkList_HeadInsert(CAL, i);
Circular_Double_LinkList_TailInsert(CBL, i);
}
PrintList(CAL);
PrintList(CBL);
Mos_2_2_18(CAL, CBL);
ClearList(CBL);
PrintList(CAL);
cout << endl;
/* 练习题2-3-19 */
cout << endl << "练习题2-3-19" << endl;
for (int i = 4; i < 7; i++) {
Circular_Double_LinkList_TailInsert(CBL, i);
Circular_Double_LinkList_HeadInsert(CBL, i);
}
for (int i = 2; i < 3; i++) {
Circular_Double_LinkList_TailInsert(CBL, i);
Circular_Double_LinkList_HeadInsert(CBL, i);
}
for (int i = 2; i < 6; i++) {
Circular_Double_LinkList_TailInsert(CBL, i);
}
PrintList(CBL);
Mos_2_2_19(CBL);
cout << endl;
/* 练习题2-3-20 */
cout << endl << "练习题2-3-20" << endl;
ClearList(DAL);
for (int i = 2; i < 6; i++) {
Double_LinkList_HeadInsert(DAL, i);
}
Double_LinkList_HeadInsert(DAL, 4);
PrintList(DAL);
Mos_2_2_20(DAL, 3);
PrintList(DAL);
Mos_2_2_20(DAL, 4);
PrintList(DAL);
cout << endl;
/* 练习题2-3-21 */
cout << endl << "练习题2-3-21" << endl;
ClearList(BL,BLTail);
for (int i = 1; i < 7; i++) {
List_HeadInsert(BL, i,BLTail);
}
PrintList(BL);
Mos_2_2_21(BL, 5);
cout << endl;
/* 练习题2-3-22 */
cout << endl << "练习题2-3-22" << endl;
ClearList(BL, BLTail);
ClearList(CL, CLTail);
for (int i = 1; i < 7; i++) {
List_HeadInsert(BL, i, BLTail);
}
for (int i = 2; i < 8; i++) {
List_HeadInsert(CL, i, CLTail);
}
Mos_2_3_8_1(BL, CL, 3, 2);
PrintList(BL);
PrintList(CL);
cout << "AL与BL在" << Mos_2_2_22(BL, CL)->data << "相同" << endl;
cout << endl;
/* 练习题2-3-23 */
cout << endl << "练习题2-3-23" << endl;
ClearList(BL, BLTail);
for (int i = 1; i < 7; i++) {
List_HeadInsert(BL, i, BLTail);
List_HeadInsert(BL, i, BLTail);
}
for (int i = -8; i < -2; i++) {
List_HeadInsert(BL, i, BLTail);
}
PrintList(BL);
Mos_2_2_23(BL, 9);
PrintList(BL);
cout << endl;
return 0;
}
王道考研2020练习题 第二章 2.3 链表 C++实现
最新推荐文章于 2022-07-10 18:25:03 发布