day01
//Day01
//在带头结点的单链表L中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一
//编写算法以实现上述操作
int delete(LinkList &L,int x)
{
if(L == nullptr || L->next == nullptr){
return 0;
}
LinkList p = L->next;
LinkList prev = L;
while(p != nullptr){
if(p->data == x){
prev->next = p->next;
delete p;
p = prev->next;
}else{
prev = p;
p = p->next;
}
}
}
代码解释:
-
初始化指针:
-
p指向链表的第一个节点(L->next)。 -
prev指向链表的头结点(L),用于记录当前节点的前一个节点。
-
-
遍历链表:
-
使用
while循环遍历链表,直到p为nullptr。
-
-
删除节点:
-
如果
p->data == x,则删除当前节点p:-
将
prev->next指向p->next,跳过p。 -
释放
p的内存。 -
更新
p为prev->next,继续检查下一个节点。
-
-
如果
p->data != x,则更新prev和p指针,继续遍历。
-
注意事项:
-
该函数假设链表是带头结点的单链表。
-
删除节点时,需要确保
prev指针正确地指向当前节点的前一个节点。 -
删除节点后,需要更新
p指针,以继续遍历链表。 -
带头节点的单链表表示为:
-
L -> [head] -> [1] -> [2] -> [3] -> [2] -> [4] -> [2] -> [5] -> nullptr prev p
day02
//day02
// 将两个有序顺序表合并为一个新的有序顺序表
bool Merge(SqList A, SqList B, SqList &C) {
if (A.length + B.length > MAX_SIZE) {
return false; // 合并后的长度超过最大容量
}
int i = 0,j = 0,k = 0;
while(i < A.length && j < B.length){
if(A.data[i] <= B.data[j]){
C.data[k] = A.data[i];
k++;
i++;
}else{
C.data[k] = B.data[j];
k++;
j++;
}
}
-
合并有序顺序表:
-
while (i < A.length && j < B.length):当A和B都还有元素时,进行循环。-
if (A.data[i] <= B.data[j]):如果A的当前元素小于等于B的当前元素,则将A的当前元素插入到C中,并移动A和C的指针。 -
else:否则,将B的当前元素插入到C中,并移动B和C的指针。
-
-
-
处理剩余元素:
-
while (i < A.length):如果A还有剩余元素,将它们全部插入到C中。 -
while (j < B.length):如果B还有剩余元素,将它们全部插入到C中。
-
-
更新合并后的线性表长度:
-
C.length = k;:更新C的长度为k,即合并后的元素个数。
-
day03
//Day03
//设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)
void Reverse(SqList &L)
{
int low = 0;
int high = L.length-1;
while(low < high){
int temp = L.data[low];
L.data[low] = L.data[high];
L.data[high] = temp;
low++;
high --;
}
}
要设计一个高效算法将顺序表 L 的所有元素逆置,并且要求算法的空间复杂度为 O(1),可以使用双指针法。具体步骤如下:
-
初始化两个指针:一个指向顺序表的头部(
left),另一个指向顺序表的尾部(right)。 -
交换元素:交换
left和right指向的元素,然后移动left指针向右,right指针向左。 -
重复步骤2:直到
left指针不再小于right指针。
day04
//Day04
//对长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,
//该算法删除线性表中所有值为x的数据元素
/*
分析:O(n)扫描一次顺序表;O(1)申请常数个辅助空间
*/
void Del_Sq(SqList &L,int x){
if(L.length == 0){
return;
}
int i = 0;
int k = 0;
while(i<L.length){
if(L.data[i] == x){
k++;
}else{
L.data[i-k] = L.data[i];
}
i++;
}
L.length = L.length-k;
}
-
使用
while循环遍历顺序表L。 -
如果当前元素
L.data[i]的值等于x,则k增加 1,表示遇到一个需要删除的元素。 -
如果当前元素
L.data[i]的值不等于x,则将该元素向前移动k个位置,即L.data[i-k] = L.data[i]。这样可以保证所有不等于x的元素都向前移动,覆盖掉前面等于x的元素。
-
时间复杂度:O(n),因为代码只遍历了一次顺序表。
-
空间复杂度:O(1),因为只使用了常数个额外的变量
i和k。//方法2 void Del_Y(SqList &L,int x){ int i = 0; int k = 0; if(L.length == 0){ return; } while(i < L.length){ if(L.data[i] != x){ k++; L.data[k] = L.data[i]; } i++; } L.length = k; } -
i是遍历顺序表的索引。 -
k用于记录当前已经保留的元素个数。
-
时间复杂度:O(n),因为代码只遍历了一次顺序表。
-
空间复杂度:O(1),因为只使用了常数个额外的变量
i和k。
day05
//Day05
//从顺序表中删除其值在给定值s与t之间(包含s和t,要求s < t)的所有元素
//如果s或t不合理或顺序表为空,则显示出错信息并退出运行
int Del_XY(SqList &L, int s, int t) {
if (L.length == 0 || s >= t) {
return -1; // 返回错误码
}
int k = 0;
for (int i = 0; i < L.length; i++) {
if (L.data[i] < s || L.data[i] > t) {
L.data[k] = L.data[i];
k++;
}
}
L.length = k;
return 1; // 返回成功码
}
day06
//Day06
//从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同
void Del_Same(SqList &L){
if(L.length == 0){
return;
}
int k = 0;//用于记录不重复元素的个数
for(int i = 1; i < L.length; i++){
if(L.data[i] != L.data[k]){
k++;
L.data[k] = L.data[i];
}
}
L.length = k+1;
}
-
使用
for循环遍历顺序表L,从第二个元素开始(即i = 1)。 -
如果当前元素
L.data[i]的值不等于前一个不重复元素L.data[k],则将该元素保留,并将其移动到L.data[k]的位置,然后k增加 1。 -
如果当前元素
L.data[i]的值等于前一个不重复元素L.data[k],则跳过该元素,不进行任何操作。
-
时间复杂度:O(n),因为代码只遍历了一次顺序表。
-
空间复杂度:O(1),因为只使用了常数个额外的变量
i和k。
day07
//Day07
/*已知一维数组A[M+N]中依次存放两个线性表
(a1,a2,a3,a4....an与b1,b2,b3...bn)
试写函数将两顺序表的位置互换,
即将b1,b2,b3...bn放在a1,a2,a3,a4....an前面*/
void Reverse(int arr[], int start,int end){
while(start < end){
swap(arr[start],arr[end]);
start++;
end--;
}
}
void SwapSequence(int arr[], int M, int N){
Reverse(arr, 0, M+N-1);
Reverse(arr, 0, N-1);
Reverse(arr, N, M+N-1);
}
day08
//Day08
//2010统考真题
//算法思想:先将前p个元素逆置,然后将后n-p个元素逆置,最后将整个顺序表逆置
void Reverse(int arr[], int start, int end) {
while (start < end) {
swap(arr[start], arr[end]);
start++;
end--;
}
}
void SwapSequence(int arr[], int length, int p) {
Reverse(arr, 0, p - 1);
Reverse(arr, p, length - 1);
Reverse(arr, 0, length - 1);
}
-
时间复杂度:O(n),因为每个逆置操作的时间复杂度为 O(n),而总共进行了三次逆置操作。
-
空间复杂度:O(1),因为只使用了常数个额外的变量。
day09
// Day09
// 试编写带头结点的的单链表L中删除一个最小值结点的高效算法(假设最小值结点是唯一的)
void Del_Min(LinkList &L) {
if (L == nullptr || L->next == nullptr) {
return;
}
LinkList minpre = L; // 最小值结点的前驱结点
LinkList min = L->next; // 最小值结点
LinkList prev = L; // 当前结点的前驱结点
LinkList p = L->next; // 当前结点
while (p != nullptr) {
if (p->data < min->data) {
min = p;
minpre = prev;
}
prev = p;
p = p->next;
}
minpre->next = min->next;
delete min;
}
-
minpre:用于记录最小值结点的前驱结点。 -
min:用于记录最小值结点。 -
prev:用于记录当前结点的前驱结点。 -
p:用于遍历链表的当前结点。
-
使用
while循环遍历链表L,从第一个结点开始(即L->next)。 -
如果当前结点
p的值小于当前最小值结点min的值,则更新min和minpre。 -
更新
prev为当前结点p,并将p指向下一个结点。
-
时间复杂度:O(n),因为需要遍历整个链表一次来找到最小值结点。
-
空间复杂度:O(1),因为只使用了常数个额外的指针变量。
day10
//Day10
//使用头插法建立单链表
void List_HeadInsert(LinkList &L,int n){
L = new Lnode;
L->next = nullptr; //创建头结点
for(int i = 0; i < n; i++){
LinkList p = new Lnode;
cout<<"请输入插入节点的数据域:";
cin>>p->data;
cout<<endl;
p->next = L->next;
L->next = p;
}
}
day11
//Day11
//使用尾插法建立单链表
void List_TailInsert(LinkList &L,int n){
L = new Lnode;
L->next = nullptr;
LinkList r = L;//尾指针r指向头结点
for(int i = 0; i < n; i++){
LinkList p = new Lnode;
cout<<"请输入新节点的数据域:";
cin>>p->data;
cout<<endl;
r->next = p;
r = p;
}
}
day12
//Day12
//试编写算法将带头结点的单链表就地逆置,
//所谓的“就地”是指辅助空间的复杂度为O (1)
LinkList Reverse_List(LinkList &L){
LinkList p, r;
p = L->next;
L->next = nullptr;
while(p != nullptr){
r = p->next;
p->next = L->next;
L->next = p;
p = r;
}
return L;
}
这里将p指向链表的第一个实际节点,并将头结点的next指针置为NULL,表示链表为空。
这个循环实现了链表的就地逆置。具体步骤如下:
-
保存
p的后继结点r,以便在逆置后继续遍历链表。 -
将
p的next指针指向当前头结点的next,即p成为新的第一个节点。 -
将头结点的
next指向p,完成逆置操作。 -
将
p指向下一个节点r,继续遍历链表。
假设你有一个带头结点的链表,初始状态如下:
L -> [头结点] -> [1] -> [2] -> [3] -> NULL
经过逆置后,链表的状态将变为:
L -> [头结点] -> [3] -> [2] -> [1] -> NULL
day13
//Day13
//设在一个带表头结点的单链表中所有元素的结点的数据值无序,试编写一个函数,
//删除表中所有介于给定的的两个值(作为函数的参数给出)之间的元素的元素(若存在)。
void Del_XY(LinkList &L,int x, int y){
if(L = nullptr || L->next = nullptr){
return; //空链表或只有一个头结点无需删除
}
LinkList p = L->next;//当前结点
LinkList prev = L; // 前一个结点
while(p->next !=nullptr){
if(p->data < x && p->data < y){
prev->next = p->next;
delete p;
p = prev->next;
}else{
prev = p;
p = p->next;
}
}
}
day14
//Day14(上)
//给定两个单链表,编写算法找出两个单链表的公共结点
LinkList search_common(LinkList &LA,linkList &LB){
LNode *p = LA->next;
LNode *q = LB->next;
while(p){
while(q){
if(p == q){
return p;
} else {
q = q->next;
}
}
p = p->next;
q = LB->next;//将q指针初始化到头结点的下一个结点
}
return NULL;//找不到就返回虚无
}
//时间复杂度:O(lenA * lenB)
//Day14(下)
//给定两个单链表,编写算法找出两个单链表的公共结点(优化算法)
LinkList search_common(LinkList &LA,LinkList &LB){
LNode *p,*q;
int k;
int lenA = length(LA);//求出链表长度
int lenB = length(LB);
if(lenA-lenB > 0){
k = lenA - lenB;//求出链表的长度差
p = LA->next;
q = LB->next;
} else {
k = lenB - lenA;
p = LB->next;
q = LA->next;
}
while(k--){
p = p->next;//p先移动k个位置
}
while(p!=NULL){
if(p == q){//若p==q,则找到公共结点
return p;
} else {
p = p->next;//若不等,同步向后移动,可以同时到达表尾
q = q->next;
}
}
return NULL;//没有公共结点
}
//时间复杂度:O(max(lenA,lenB));
day15
//Day15
//将一个带头结点的单链表A分解为两个带头结点的单链表A和B,
//使得A表中含有原表中序号为奇数的元素,
//而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变
LinkList DisCreate_L(LinkList &A){
LinkList B = new Lnode;
B->next = nullptr; //初始化单链表B
LinkList a = A;
LinkList b = B;
LinkList p = A->next; //原A链表第一个结点
A->next = NULL;
int i = 0;
while(p != nullptr){
i++;
if(i%2 == 0){ // 偶数
b->next = p;
b = p;
}else{
a->next = p;
a = p;
}
p = p->next;
}
a->next = nullptr;
b->next = nullptr;
return B;
}
-
a指向链表A的头结点。 -
b指向链表B的头结点。 -
p指向原链表A的第一个实际节点。 -
将链表
A的头结点的next指针置为nullptr,表示链表A为空。 -
使用计数器
i记录当前节点的序号。 -
如果当前节点的序号为偶数,则将该节点插入到链表
B的尾部,并更新b指针。 -
如果当前节点的序号为奇数,则将该节点插入到链表
A的尾部,并更新a指针。 -
p指向下一个节点,继续遍历。 -
将链表
A的最后一个节点的next指针置为nullptr,表示链表A的结束。 -
将链表
B的最后一个节点的next指针置为nullptr,表示链表B的结束
day16
//Day16
//设C={a1,b1,a2,b2,...an,bn}为线性表,采用带头结点的hc单链表存放,
//设计一个就地算法,将其拆分为两个线性表,
//使得A={a1,a2,..., an},B={ bn,...,b2,b1}
LinkList Discreate(LinkList &C,LinkList &A, LinkList &B){
A = new Lnode;
A->next = nullptr;
B = new Lnode;
B->next = nullptr;
LinkList p = C->next;
C->next = nullptr;
LinkList ra = A;
LinkList rb;
while(p != nullptr){
ra->next = p;
ra = p;
p = p->next;
if(p){
rb = p->next;
p->next = B->next;
B->next = p;
p = rb;
}
}
ra->next = nullptr;
return A,B;
}
详细步骤
-
初始化链表 A 和 B:
-
A = new Lnode;:创建链表A的头结点。 -
A->next = nullptr;:将链表A的头结点的next指针设置为nullptr。 -
B = new Lnode;:创建链表B的头结点。 -
B->next = nullptr;:将链表B的头结点的next指针设置为nullptr。
-
-
初始化指针:
-
LinkList p = C->next;:将指针p指向链表C的第一个元素。 -
C->next = nullptr;:断开链表C的头结点,使其成为一个空链表。 -
LinkList ra = A;:将指针ra指向链表A的头结点,用于构建链表A。 -
LinkList rb;:声明指针rb,用于构建链表B。
-
-
遍历链表 C:
-
while (p != nullptr):当p不为nullptr时,继续遍历链表C。
-
-
插入链表 A:
-
ra->next = p;:将p插入到链表A的末尾。 -
ra = p;:将ra指向链表A的最后一个节点。 -
p = p->next;:将p指向下一个节点。
-
-
插入链表 B:
-
if (p != nullptr):检查p是否为nullptr,确保还有下一个节点可以插入到链表B。 -
rb = p->next;:保存p的下一个节点。 -
p->next = B->next;:将p插入到链表B的头部。 -
B->next = p;:更新链表B的头指针。 -
p = rb;:将p指向下一个节点。
-
-
断开链表 A 的最后一个节点:
-
ra->next = nullptr;:确保链表A的最后一个节点的next指针为nullptr。
-
-
返回链表 A 和 B:
-
return A, B;:返回链表A和B。
-
day17
//Day17
//在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,
//设计算法去掉数值相同的元素,使表中不再有重复的元素,
//例如 (7,10,10,21,30,42,42,42,51,70)将变成(7,10,21,30,42,51,70)
void Del_same(LinkList &L){
LinkList pre = L->next;
LinkList p = pre->next;
while(p != nullptr){
if(pre->data == p->data){
pre->next = p->next;
delete p;
}
pre = pre->next;
p = p->next;
}
}
-
初始化指针:
-
LinkList pre = L->next;:将指针pre指向链表的第一个节点。 -
LinkList p = pre->next;:将指针p指向链表的第二个节点。
-
day18
// 归并两个递增链表为一个递减链表
LinkList Merge(LinkList &A, LinkList &B) {
LinkList C = new Lnode; // 创建归并后的链表 C 的头结点
C->next = nullptr;
LinkList a = A->next; // a 指向链表 A 的第一个节点
LinkList b = B->next; // b 指向链表 B 的第一个节点
LinkList r; // 用于保存下一个节点的指针
while (a != nullptr && b != nullptr) {
if (a->data < b->data) { // 如果 a 的值小于 b 的值
r = a->next; // 保存 a 的下一个节点
a->next = C->next; // 将 a 插入到链表 C 的头部
C->next = a;
a = r; // a 指向下一个节点
} else {
r = b->next; // 保存 b 的下一个节点
b->next = C->next; // 将 b 插入到链表 C 的头部
C->next = b;
b = r; // b 指向下一个节点
}
}
// 处理剩余的节点
while (a != nullptr) {
r = a->next; // 保存 a 的下一个节点
a->next = C->next; // 将 a 插入到链表 C 的头部
C->next = a;
a = r; // a 指向下一个节点
}
while (b != nullptr) {
r = b->next; // 保存 b 的下一个节点
b->next = C->next; // 将 b 插入到链表 C 的头部
C->next = b;
b = r; // b 指向下一个节点
}
return C; // 返回归并后的链表 C
}
day19
//Day19
//设A和B是两个单链表(带头结点),其中元素递增有序。
//设计一个算法从A和B中的公共元素产生单链表c,要求不破坏A、B的结点。
// 从A和B中的公共元素产生单链表C
LinkList Search_Common(LinkList &A, LinkList &B) {
LinkList C = new Lnode; // 创建链表 C 的头结点
C->next = nullptr;
LinkList r = C; // r 指向链表 C 的最后一个节点
LinkList p = A->next; // p 指向链表 A 的第一个节点
LinkList q = B->next; // q 指向链表 B 的第一个节点
while (p != nullptr && q != nullptr) {
if (p->data < q->data) {
p = p->next; // 移动 p 指针
} else if (p->data > q->data) {
q = q->next; // 移动 q 指针
} else {
// 找到公共元素
LinkList s = new Lnode; // 创建新节点
s->data = p->data; // 赋值
r->next = s; // 将新节点插入到链表 C 的末尾
r = s; // 更新 r 指针
p = p->next; // 移动 p 指针
q = q->next; // 移动 q 指针
}
}
r->next = nullptr; // 断开链表 C 的最后一个节点
return C; // 返回归并后的链表 C
}
day20
//Day20
//已知两个链表A和B分别表示两个集合,其元素递增有序排列。
//编制函数,求A和B的交集,并存放于A链表中。
//分析:元素递增;不能创建一个新链表,求完交集后,A链表中只有相同的元素(A&B的交集元素)
void Insert_same(LinkList &A, LinkList &B) {
LinkList p = A->next; // p 指向链表 A 的第一个节点
LinkList q = B->next; // q 指向链表 B 的第一个节点
LinkList prev = A; // prev 指向链表 A 的头结点
while (p != nullptr && q != nullptr) {
if (p->data < q->data) {
// 如果 p 的值小于 q 的值,删除 p 节点
prev->next = p->next;
delete p;
p = prev->next;
} else if (p->data > q->data) {
// 如果 p 的值大于 q 的值,移动 q 指针
q = q->next;
} else {
// 如果 p 的值等于 q 的值,移动 p 和 q 指针
prev = p;
p = p->next;
q = q->next;
}
}
// 如果 p 还有剩余节点,删除剩余节点
while (p != nullptr) {
prev->next = p->next;
delete p;
p = prev->next;
}
}
day21
//Day21
//两个整数序列A=al,a2,a3 ...am和B=b1,b2,b3...,bn已经存入两个单链表中,
//设计一个算法,判断序列B是否是序列A的连续子序列
bool IsSon_L(LinkList &A, LinkList &B){
LinkList p = A->next;
LinkList q = B->next;
while(p != nullptr){
LinkList temp_p = p;
LinkList temp_q = q;
while(temp_p != nullptr && temp_q != nullptr &&temp_p->data == temp_q->data){
temp_p = temp_p->next;
temp_q = temp_q->next;
}
if(temp_q == nullptr){
return true;
}
p = p->next;
}
return false;
}
代码解释
-
初始化指针:
-
LinkList p = A->next;:将指针p指向链表A的第一个节点。 -
LinkList q = B->next;:将指针q指向链表B的第一个节点。
-
-
遍历链表
A:-
while (p != nullptr):当p不为nullptr时,继续遍历链表A。
-
-
检查子序列:
-
LinkList temp_p = p;:保存p的当前位置。 -
LinkList temp_q = q;:保存q的当前位置。 -
while (temp_p != nullptr && temp_q != nullptr && temp_p->data == temp_q->data):当temp_p和temp_q都不为nullptr且它们的值相等时,继续遍历。 -
if (temp_q == nullptr):如果temp_q为nullptr,说明B的所有元素在A中按顺序连续出现,返回true。
-
-
继续检查:
-
p = p->next;:继续检查A的下一个节点。
-
-
返回结果:
-
如果遍历完
A都没有找到B的所有元素按顺序连续出现,返回false。
-
day22
//Day22
//设计一个算法用于判断带头结点的循环双链表是否对称。
int Symmetry(DLinkList &D){
DLinkList p = D->next;
DLinkList q = D->prev;
while(p != q && q->prev !=p){
if(p->data == q->data){
p = p->next;
q = q->prev;
}else{
return 0;
}
}
return 1;
}
详细步骤
-
初始化指针:
-
DLinkList p = D->next;:将指针p指向链表的第一个实际数据结点。 -
DLinkList q = D->prev;:将指针q指向链表的最后一个实际数据结点。
-
-
循环条件:
-
while(p != q && q->prev != p):当p和q没有相遇或交叉时,继续循环。 -
p != q:表示p和q还没有相遇。 -
q->prev != p:表示q的前一个结点不是p,即p和q还没有交叉。
-
-
比较数据:
-
if(p->data == q->data):比较p和q指向的结点的数据。 -
如果数据相等,则继续移动指针
p和q。 -
p = p->next;:将指针p向后移动到下一个结点。 -
q = q->prev;:将指针q向前移动到前一个结点。
-
-
发现不对称:
-
else:如果p和q指向的结点的数据不相等,则链表不对称。 -
return 0;:返回0,表示链表不对称。
-
-
链表对称:
-
如果循环结束时没有发现不对称的情况,则链表对称。
-
return 1;:返回1,表示链表对称。
-
示例
假设我们有以下循环双链表:
头结点 -> 1 -> 2 -> 3 -> 2 -> 1 -> 头结点
-
初始时,
p指向1,q指向1。 -
第一次循环:比较
1和1,相等,p指向2,q指向2。 -
第二次循环:比较
2和2,相等,p指向3,q指向3。 -
第三次循环:比较
3和3,相等,p指向2,q指向2。 -
第四次循环:比较
2和2,相等,p指向1,q指向1。 -
此时,
p == q,循环结束。
由于所有对应位置的元素都相等,链表对称,函数返回 1。
day23
//Day23
//有两个循环单链表,链表头指针分别为h1和h2,
//编写一个函数将链表h2链接到链表h1之后,
//要求链接后的链表仍保持循环链表的形式
LinkList Link(LinkList &h1, LinkList &h2){
LinkList p = h1;
LinkList q = h2;
while(p->next != h1){
p = p->next; //找到h1尾结点的前一个结点
}
while(q->next != h2){
q =q->next; //找到h2尾结点的前一个结点
}
p->next = h2->next;
q->next = h1;
return h1;
}
将 h2 链接到 h1 之后
p->next = h2->next; // h1 的尾结点指向 h2 的第一个实际数据结点
q->next = h1; // h2 的尾结点指向 h1 的头结点
day24
// Day24
// 设有一个带头结点的的循环单链表,其结点值均为正整数。
// 设计一个算法,反复找出单链表中结点值最小的结点并输出,
// 然后将该结点从中删除直到单链表为空为止,再删除表头结点。
void Del_All(LinkList &L) {
while (L->next != L) { // 当链表不为空时
LinkList minprev = L;
LinkList min = L->next;
LinkList prev = L;
LinkList p = L->next;
// 找到最小值结点
while (p != L) {
if (p->data < min->data) {
min = p;
minprev = prev;
}
prev = p;
p = p->next;
}
// 输出最小值结点
cout << min->data << " ";
// 删除最小值结点
minprev->next = min->next;
delete min;
}
// 删除表头结点
delete L;
L = NULL;
}
day31
//Day31
//已知一棵二叉树按顺序存储结构进行存储,设计一个算法,
//求编号分别为i和j的两个结点的最近公共祖先结点的值。
//算法思想:不断将较大的i和j取一半,直到i=j,找到了最近的公共祖先结点
int Comn_Ancestor(const vector<int> &tree, int i, int j) {
while (i != j) {
if (i > j) {
i = i / 2;
} else {
j = j / 2;
}
}
return tree[i];
}
1523

被折叠的 条评论
为什么被折叠?



