代码
-
编写一个将给定的线性单链表逆转的函数,只允许改变结点的指针值,不允许移动结点值,返回逆转后的链表的头指针。
Node* reverse_Linklist(Node* head) // 带头结点 { // 空表返回头结点 if(!head->next) return head; else { Node* p = head->next; Node* tmp = NULL; // 待修改指针的结点 Node* front = NULL; // 存放tmp的上一个结点 // 由于尾结点指向NULL,初始化为NULL while (p->next) { tmp = p; p = p->next; tmp->next = front; // 指向上一个结点 front = tmp; // 更新front } p->next = front; // 修改尾结点的指针 head->next = p; // 头结点指向原来的尾结点 return head; } }
-
对于给定的单链表,编写一个把值为 a 的结点插在值为 b 的结点的前面的函数。若值为b的结点不在线性链表中,则把 a 插在链表的最后。若有多个值为 b 的结点,则插在第一个出现的 b 结点之前。
Node* insertLinklist_t2(Node* head, int a, int b) // 把值为 a 的结点插在值为 b 的结点前面 { if(!head->next) return head; else { Node* tmp = new Node; tmp->data = a; Node* p = head; while (p->next) // 找值为b的结点 { if(p->next->data==b) break; p = p->next; } tmp->next = p->next; p->next = tmp; return head; } }
-
(已改正)假设 A 和 B 是两个按结点值从小到大排列的有序环形链表(带表头结点,表头结点中不存放有效信息)。试编写一个将这两个有序的环形链表归并为一个按节点值从小到大排列的有序环形链表的 C 函数。
Node* MergeLinkList(Node* head1, Node* head2)
{
Node* p1 = head1->next;
Node* p2 = head2->next;
Node* head = p1->data<p2->data? head1:head2; // 挑选首结点较小的头结点作为头结点
Node* front = head; // 记录当前结点,作为遍历时结点的上一个结点
while (p1!=head1 && p2!=head2)
{
if(p1->data<p2->data)
{
front->next = p1;
front = p1;
p1 = p1->next;
}
else
{
front->next = p2;
front = p2;
p2 = p2->next;
}
}
while(p1!=head1)
{
front->next = p1;
front = p1;
p1 = p1->next;
}
while (p2!=head2)
{
front->next = p2;
front = p2;
p2 = p2->next;
}
front->next = head;
return head;
}
-
求广义表的深度。我们规定空的广义表的深度为 0,而一般地有
d e p t h ( s ) = { 1 , 若 s 是 一 个 原 子 1 + m a x { d e p t h ( a 0 ) , ⋯ , d e p t h ( a n − 1 ) , 若 s 是 广 义 表 ( a 0 , a 1 , ⋯ , a n − 1 ) } depth(s)= \begin{cases} 1, & 若s是一个原子 \\ 1+max\{depth(a_0),\cdots,depth(a_{n-1}), & 若s是广义表(a_0, a_1, \cdots, a_{n-1})\} \end{cases} depth(s)={1,1+max{depth(a0),⋯,depth(an−1),若s是一个原子若s是广义表(a0,a1,⋯,an−1)}
编写一个求解广义表 s s s的深度的C函数。-
思考
-
如果是一个递归表,你的函数会输出什么结果?
广义表 C = ( a , C ) C=(a, C) C=(a,C), a a a为原子, C C C为一个广义表
-
在写递归程序时,需要特别注意哪些情况?
-
int glistDepth(GNode* C) { if (!C) // 如果C为空表,返回长度0 { return 0; } if (C->tag == 0) // 如果C为原子,返回长度1 { return 1; } int max = 0; for (GNode* p = C; p; p = p->ptr.tp) // 遍历每一个子表,寻找最大深度 { int depth = glistDepth(p->ptr.hp); if (max < depth) max = depth; } return max+1; }
注意判断空表情况 注意判断递归终止条件:子表为原子的情况
-
附录
测试代码:
-
#include<bits/stdc++.h> using namespace std; typedef struct node { int data; struct node* next; }Node; Node* initLinklist(Node* head) { head = new Node; head->data = 0; head->next = NULL; return head; } Node* insertLinklist(Node* head, int n) // 尾插 { Node* L = head; for(int i = 0; i < n; i++) { Node* p = new Node; cin>>p->data; p->next = NULL; L->next = p; L = p; } return head; } void printLinklist(Node* head) { Node* p = head->next; while (p) { cout<<p->data<<' '; p = p->next; } cout<<endl; } Node* reverse_Linklist(Node* head) // 带头结点 { // 空表返回头结点 if(!head->next) return head; else { Node* p = head->next; Node* tmp = NULL; // 待修改指针的结点 Node* front = NULL; // 存放tmp的上一个结点 // 由于尾结点指向NULL,初始化为NULL while (p->next) { tmp = p; p = p->next; tmp->next = front; // 指向上一个结点 front = tmp; // 更新front } p->next = front; // 修改尾结点的指针 head->next = p; // 头结点指向原来的尾结点 return head; } } int main() { Node* head; head = initLinklist(head); cout<<"Please enter the number of elements"<<endl; int n; cin>>n; cout<<"Please enter the values(>0) of elements"<<endl; insertLinklist(head, n); cout<<"The original order is:"<<endl; printLinklist(head); reverse_Linklist(head); cout<<"The reversed order is:"<<endl; printLinklist(head); system("pause"); return 0; }
-
#include<bits/stdc++.h> using namespace std; typedef struct node { int data; struct node* next; }Node; Node* initLinklist(Node* head) { head = new Node; head->data = 0; head->next = NULL; return head; } Node* insertLinklist(Node* head, int n) { Node* L = head; for(int i = 0; i < n; i++) { Node* p = new Node; cin>>p->data; p->next = NULL; L->next = p; L = p; } return head; } Node* insertLinklist_t2(Node* head, int a, int b) // 把值为 a 的结点插在值为 b 的结点前面 { if(!head->next) return head; else { Node* tmp = new Node; tmp->data = a; Node* p = head; while (p->next) // 找值为b的结点 { if(p->next->data==b) break; p = p->next; } tmp->next = p->next; p->next = tmp; return head; } } void printLinklist(Node* head) { Node* p = head->next; while (p) { cout<<p->data<<' '; p = p->next; } cout<<endl; } int main() { Node* head; head = initLinklist(head); cout<<"Please enter the number of elements"<<endl; int n; cin>>n; cout<<"Please enter the values(>0) of elements"<<endl; insertLinklist(head, n); cout<<"The original order is:"<<endl; printLinklist(head); insertLinklist_t2(head, 1, 2); cout<<"The inserted order is:"<<endl; printLinklist(head); system("pause"); return 0; }
-
#include<bits/stdc++.h> using namespace std; typedef struct node { int data; struct node* next; }Node; Node* initCircularList(Node* head) { head = new Node; head->data = 0; head->next = head; return head; } Node* insertCircularList(Node* head, int n) // 尾插 { Node* L = head; for(int i = 0; i < n; i++) { Node* p = new Node; cin>>p->data; p->next = L->next; L->next = p; L = p; } return head; } Node* MergeLinkList(Node* head1, Node* head2) { Node* p1 = head1->next; Node* p2 = head2->next; Node* head = p1->data<p2->data? head1:head2; // 挑选首结点较小的头结点作为头结点 Node* front = head; // 记录当前结点,作为遍历时结点的上一个结点 while (p1!=head1 && p2!=head2) { if(p1->data<p2->data) { front->next = p1; front = p1; p1 = p1->next; } else { front->next = p2; front = p2; p2 = p2->next; } } while(p1!=head1) { front->next = p1; front = p1; p1 = p1->next; } while (p2!=head2) { front->next = p2; front = p2; p2 = p2->next; } front->next = head; return head; } void printCircularList(Node* head) { Node* p = head->next; while (p!=head) { cout<<p->data<<' '; p = p->next; } cout<<endl; } int main() { Node* head1, *head2; head1 = initCircularList(head1); head2 = initCircularList(head2); cout<<"Please enter the number of elements in list1:"<<endl; int n1; cin>>n1; cout<<"Please enter the values of elements in list1:"<<endl; insertCircularList(head1, n1); cout<<"The original order of list1 is:"<<endl; printCircularList(head1); cout<<"Please enter the number of elements in list2:"<<endl; int n2; cin>>n2; cout<<"Please enter the values of elements in list2:"<<endl; insertCircularList(head2, n2); cout<<"The original order of list2 is:"<<endl; printCircularList(head2); cout<<"The merged list is:"<<endl; Node* head = MergeLinkList(head1, head2); printCircularList(head); system("pause"); return 0; } // 3 // 1 4 6 // 4 // 2 3 5 7
-
#include<bits/stdc++.h> using namespace std; typedef struct node { int tag; union { char atom; struct { struct node* hp, * tp; }ptr; }; }GNode, *Glist; Glist creatGlist(Glist C) { //广义表C C = (Glist)malloc(sizeof(Glist)); C->tag = 1; //表头原子‘a’ C->ptr.hp = (Glist)malloc(sizeof(Glist)); C->ptr.hp->tag = 0; C->ptr.hp->atom = 'a'; //表尾子表(b,c,d),是一个整体 C->ptr.tp = (Glist)malloc(sizeof(Glist)); C->ptr.tp->tag = 1; C->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist)); C->ptr.tp->ptr.tp = NULL; //开始存放下一个数据元素(b,c,d),表头为‘b’,表尾为(c,d) C->ptr.tp->ptr.hp->tag = 1; C->ptr.tp->ptr.hp->ptr.hp = (Glist)malloc(sizeof(Glist)); C->ptr.tp->ptr.hp->ptr.hp->tag = 0; C->ptr.tp->ptr.hp->ptr.hp->atom = 'b'; C->ptr.tp->ptr.hp->ptr.tp = (Glist)malloc(sizeof(Glist)); //存放子表(c,d),表头为c,表尾为d C->ptr.tp->ptr.hp->ptr.tp->tag = 1; C->ptr.tp->ptr.hp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist)); C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag = 0; C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom = 'c'; C->ptr.tp->ptr.hp->ptr.tp->ptr.tp = (Glist)malloc(sizeof(Glist)); //存放表尾d C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag = 1; C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist)); C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag = 0; C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->atom = 'd'; C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp = NULL; return C; } int glistDepth(GNode* C) { if (!C) // 如果C为空表,返回长度0 { return 0; } if (C->tag == 0) // 如果C为原子,返回长度1 { return 1; } int max = 0; for (GNode* p = C; p; p = p->ptr.tp) // 遍历每一个子表,寻找最大深度 { int depth = glistDepth(p->ptr.hp); if (max < depth) max = depth; } return max+1; } int main() { GNode* C = NULL; C = creatGlist(C); cout << glistDepth(C) << endl; return 0; }