唐策善+刘黄生+《数据结构——用C语言描述》+课后题答案
- 格式:doc
- 大小:4.14 MB
- 文档页数:45
数据结构课后习题参考答案第一章绪论1.3 (1) O(n)(2)(2)O(n)(3)(3)O(n)(4)(4)O(n1/2)(5)(5)执行程序段的过程中,x,y值变化如下:循环次数x y0(初始)91 1001 92 1002 93 100………………9 100 10010 101 10011 91 9912 92 100………………20 101 9921 91 98………………30 101 9831 91 97到y=0时,要执行10*100次,可记为O(10*y)=O(n)1.5 2100 , (2/3)n , log2n , n1/2 ,n3/2, (3/2)n , n log2n , 2 n ,n! , n n第二章线性表(参考答案)在以下习题解答中,假定使用如下类型定义:(1)顺序存储结构:#define MAXSIZE 1024typedef int ElemType;// 实际上,ElemType可以是任意类型typedef struct{ ElemType data[MAXSIZE];int last; // last表示终端结点在向量中的位置}sequenlist;(2)链式存储结构(单链表)typedef struct node{ElemType data;struct node *next;}linklist;(3)链式存储结构(双链表)typedef struct node{ElemType data;struct node *prior,*next;}dlinklist;(4)静态链表typedef struct{ElemType data;int next;}node;node sa[MAXSIZE];2.1 头指针:指向链表的指针。
因为对链表的所有操均需从头指针开始,即头指针具有标识链表的作用,所以链表的名字往往用头指针来标识。
如:链表的头指针是la,往往简称为“链表la”。
第1章绪论5.选择题:CCBDCA6.试分析下面各程序段的时间复杂度。
(1)O(1)(2)O(m*n)(3)O(n2)(4)O(log3n)(5)因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O(n2)(6)O(n)第2章线性表1.选择题babadbcabdcddac2.算法设计题(6)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。
ElemType Max (LinkList L ){if(L->next==NULL) return NULL;pmax=L->next; 法设计题(2)回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。
试写一个算法判定给定的字符向量是否为回文。
(提示:将一半字符入栈)?根据提示,算法可设计为:合应用题(1)已知模式串t=‘abcaabbabcab’写出用KMP法求得的每个字符对应的next和nextval函数值。
(3)数组A中,每个元素A[i,j]的长度均为32个二进位,行下标从-1到9,列下标从1到11,从首地址S开始连续存放主存储器中,主存储器字长为16位。
求:①存放该数组所需多少单元②存放数组第4列所有元素至少需多少单元③数组按行存放时,元素A[7,4]的起始地址是多少④数组按列存放时,元素A[4,7]的起始地址是多少每个元素32个二进制位,主存字长16位,故每个元素占2个字长,行下标可平移至1到11。
(1)242 (2)22 (3)s+182 (4)s+142(4)请将香蕉banana用工具 H( )—Head( ),T( )—Tail( )从L中取出。
L=(apple,(orange,(strawberry,(banana)),peach),pear)H(H(T(H(T(H(T(L)))))))(5)写一个算法统计在输入字符串中各个不同字符出现的频度并将结果存入文件(字符串中的合法字符为A-Z这26个字母和0-9这10个数字)。
数据结构(c语言版)课后习题答案完整版数据结构(C语言版)课后习题答案完整版一、数据结构概述数据结构是计算机科学中一个重要的概念,用来组织和存储数据,使之可以高效地访问和操作。
在C语言中,我们可以使用不同的数据结构来解决各种问题。
本文将提供完整版本的C语言数据结构的课后习题答案。
二、顺序表1. 顺序表的定义和基本操作顺序表是一种线性表,其中的元素在物理内存中连续地存储。
在C 语言中,我们可以通过定义结构体和使用指针来实现顺序表。
以下是顺序表的一些基本操作的答案:(1)初始化顺序表```ctypedef struct{int data[MAX_SIZE];int length;} SeqList;void InitList(SeqList *L){L->length = 0;}```(2)插入元素到顺序表中```cbool Insert(SeqList *L, int pos, int elem){if(L->length == MAX_SIZE){return false; // 顺序表已满}if(pos < 1 || pos > L->length + 1){return false; // 位置不合法}for(int i = L->length; i >= pos; i--){L->data[i] = L->data[i-1]; // 向后移动元素 }L->data[pos-1] = elem;L->length++;return true;}```(3)删除顺序表中的元素```cbool Delete(SeqList *L, int pos){if(pos < 1 || pos > L->length){return false; // 位置不合法}for(int i = pos; i < L->length; i++){L->data[i-1] = L->data[i]; // 向前移动元素 }L->length--;return true;}```(4)查找顺序表中的元素```cint Search(SeqList L, int elem){for(int i = 0; i < L.length; i++){if(L.data[i] == elem){return i + 1; // 找到元素,返回位置 }}return -1; // 未找到元素}```2. 顺序表习题解答(1)逆置顺序表```cvoid Reverse(SeqList *L){for(int i = 0; i < L->length / 2; i++){int temp = L->data[i];L->data[i] = L->data[L->length - 1 - i]; L->data[L->length - 1 - i] = temp;}}```(2)顺序表元素去重```cvoid RemoveDuplicates(SeqList *L){for(int i = 0; i < L->length; i++){for(int j = i + 1; j < L->length; j++){if(L->data[i] == L->data[j]){Delete(L, j + 1);j--;}}}}```三、链表1. 单链表单链表是一种常见的链式存储结构,每个节点包含数据和指向下一个节点的指针。
第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
在有些情况下,数据元素也称为元素、结点、记录等。
数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
例如,学生基本信息表中的学号、姓名、性别等都是数据项。
数据对象:是性质相同的数据元素的集合,是数据的一个子集。
例如:整数数据对象是集合N={0,±1,±2,…},字母字符数据对象是集合C={‘A’,‘B’,…,‘Z’,‘a’,‘b’,…,‘z’},学生基本信息表也可是一个数据对象。
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。
逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。
因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。
存储结构:数据对象在计算机中的存储表示,也称为物理结构。
抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。
具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。
2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。
答案:例如有一张学生基本信息表,包括学生的学号、姓名、性别、籍贯、专业等。
每个学生基本信息记录对应一个数据元素,学生记录按顺序号排列,形成了学生基本信息记录的线性序列。
国家计算机等级考试二级C语言公共基础知识总结第一章数据结构与算法1.1 算法算法:是指解题方案的准确而完整的描述。
算法不等于程序,也不等计算机方法,程序的编制不可能优于算法的设计。
算法的基本特征:是一组严谨地定义运算顺序的规则,每一个规则都是有效的,是明确的,此顺序将在有限的次数下终止。
特征包括:(1)可行性;(2)确定性,算法中每一步骤都必须有明确定义,不充许有模棱两可的解释,不允许有多义性;(3)有穷性,算法必须能在有限的时间内做完,即能在执行有限个步骤后终止,包括合理的执行时间的含义;(4)拥有足够的情报。
算法的基本要素:一是对数据对象的运算和操作;二是算法的控制结构。
指令系统:一个计算机系统能执行的所有指令的集合。
基本运算包括:算术运算、逻辑运算、关系运算、数据传输。
算法的控制结构:顺序结构、选择结构、循环结构。
算法基本设计方法:列举法、归纳法、递推、递归、减斗递推技术、回溯法。
算法复杂度:算法时间复杂度和算法空间复杂度。
算法时间复杂度是指执行算法所需要的计算工作量。
算法空间复杂度是指执行这个算法所需要的内存空间。
1.2 数据结构的基本基本概念数据结构研究的三个方面:(1)数据集合中各数据元素之间所固有的逻辑关系,即数据的逻辑结构;(2)在对数据进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构;(3)对各种数据结构进行的运算。
数据结构是指相互有关联的数据元素的集合。
数据的逻辑结构包含:(1)表示数据元素的信息;(2)表示各数据元素之间的前后件关系。
数据的存储结构有顺序、链接、索引等。
线性结构条件:(1)有且只有一个根结点;(2)每一个结点最多有一个前件,也最多有一个后件。
非线性结构:不满足线性结构条件的数据结构。
1.3 线性表及其顺序存储结构线性表是由一组数据元素构成,数据元素的位置只取决于自己的序号,元素之间的相对位置是线性的。
在复杂线性表中,由若干项数据元素组成的数据元素称为记录,而由多个记录构成的线性表又称为文件。
第一章绪论课堂习题1、试写一算法,自大到小依次输出顺序读入的三个整数X,Y和Z的值。
【解答】一解:IF X<Y X<->Y;IF Y>Z Y<->Z;IF X<Y X<->Y;此算法最坏情况下比较3次,移动(即赋值9次)二解: IF X<Y {TEMP=X;X=Y;Y=TEMP;}IF Y<Z {TEMP=Z;Z=Y;IF X>TEMP Y=TEMPELSE{Y=X;X=TEMP;}此算法最坏情况下比较3次,移动7次三解: IF X<Y{IF Y>Z X<->YELSE X<->Z;}ELSE{IF X<Z X<->Z;}IF Y<Z Y<-Z;此算法最坏情况下比较3次,移动6次2、抽象数据类型三元组的定义、表示和实现【解答】抽象数据类型三元组的定义已经给出(见教材12页),要求设计实现三元组基本操作的演示程序。
#include <stdio.h>#include <stdlib.h>typedef int ElemType;typedef ElemType *Triplet;typedef int Status;#define OK 1#define ERROR 0#define OVERFLOW -2Status InitTriplet(Triplet *T){ElemType v1,v2,v3;*T=(ElemType *)malloc(3*sizeof(ElemType));if (*T==0) return(OVERFLOW);scanf("%d,%d,%d",&v1,&v2,&v3);(*T)[0]=v1; (*T)[1]=v2; (*T)[2]=v3;}Status DestroyTriplet(Triplet *T){free(*T);*T=NULL;}Status Get(Triplet T,int i,ElemType *e){if (i<1||i>3) return ERROR;*e=T[i-1]; return OK;}Status Put(Triplet T,int i,ElemType e){if (i<1||i>3) return ERROR;(*T)[i-1]=e; return OK;}Status IsAscending(Triplet T){return((T[0]<T[1])&&(T[1]<T[2]));}Status IsDescending(Triplet T){return((T[0]>T[1])&&(T[1]>T[2]));}Status Max(Triplet T,ElemType *e){*e=(T[0]>=T[1]?((T[0]>=T[2])?T[0]:T[2]):((T[1]>=T[2])?T[1]:T[2]); return OK;}Status Min(Triplet T,ElemType *e){*e=(T[0]<=T[1]?((T[0]<=T[2])?T[0]:T[2]):((T[1]<=T[2])?T[1]:T[2]); return OK;}void main(){Triplet T;ElemType e;int select,i;printf("请输入三个数,建立一个三元组:\n");if (InitTriplet(&T)==OVERFLOW)printf("存储空间分配失败,退出程序\n");else{do{printf("1:取三元组第I个元素\n");printf("2:修改三元组第I个元素\n");printf("3:判断三元组元素是否递增\n");printf("4:判断三元组元素是否递减\n");printf("5:取三元组最大元\n");printf("6:取三元组最小元\n");printf("0:结束\n");scanf("&d",&select);switch(select){case 1:printf("\ni=");scanf("%d",&i);if (Get(T,i,&e)==ERROR) printf("I值输入不合法\n");else printf("第I个元素的值为%d\n",e); break;case 2:printf("\ni=");scanf("%d",&i);printf("\ne=");scanf("%d",&e);if (Put(T,i,e)==ERROR)p printf("I值输入不合法\n");else printf("新三元组为:%4d%4d%4d\n",T[0],T[1],T[2]);break;case 3:if (IsAscending(T)==1) printf("三元组递增有序\n");else printf("三元组非递增\n"); break;case 4:if (IsDescending(T)==1) printf("三元组递减有序\n");else printf("三元组非递减\n"); break;case 5:Max(T,&e);printf("三元组的最大元为%d\n",e); break;case 6:Min(T,&e);printf("三元组的最小元为%d\n",e); break;case 0:printf("操作结束\n"); break;default:printf("选择出错,请输入数字(0-6)\n");}} while (select!=0);DestroyTriplet(&T);}}课后练习一、问答题1.什么是数据结构?2.叙述四类基本数据结构的名称与含义。
第一章答案1.3计算下列程序中x=x+1的语句频度for(i=1;i<=n;i++)for(j=1;j<=i;j++)for(k=1;k<=j;k++)x=x+1;【解答】x=x+1的语句频度为:T(n)=1+(1+2)+(1+2+3)+……+(1+2+……+n)=n(n+1)(n+2)/61. 4试编写算法,求p n(x)=a0+a1x+a2x2+…….+a n x n的值p n(x0),并确定算法中每一语句的执行次数和整个算法的时间复杂度,要求时间复杂度尽可能小,规定算法中不能使用求幂函数。
注意:本题中的输入为a i(i=0,1,…n)、x和n,输出为P n(x0)。
算法的输入和输出采用下列方法(1)通过参数表中的参数显式传递(2)通过全局变量隐式传递。
讨论两种方法的优缺点,并在算法中以你认为较好的一种实现输入输出。
【解答】(1)通过参数表中的参数显式传递优点:当没有调用函数时,不占用内存,调用结束后形参被释放,实参维持,函数通用性强,移置性强。
缺点:形参须与实参对应,且返回值数量有限。
(2)通过全局变量隐式传递优点:减少实参与形参的个数,从而减少内存空间以及传递数据时的时间消耗缺点:函数通用性降低,移植性差算法如下:通过全局变量隐式传递参数PolyValue(){ int i,n;float x,a[],p;printf(“\nn=”);scanf(“%f”,&n);printf(“\nx=”);scanf(“%f”,&x);for(i=0;i<n;i++)scanf(“%f ”,&a[i]); /*执行次数:n次*/p=a[0];for(i=1;i<=n;i++){ p=p+a[i]*x; /*执行次数:n次*/x=x*x;}printf(“%f”,p);}算法的时间复杂度:T(n)=O(n)通过参数表中的参数显式传递float PolyValue(float a[ ], float x, int n){float p,s;int i;p=x;s=a[0];for(i=1;i<=n;i++){s=s+a[i]*p; /*执行次数:n次*/p=p*x;}return(p);}算法的时间复杂度:T(n)=O(n)第二章答案约瑟夫环问题约瑟夫问题的一种描述为:编号1,2,…,n的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数)。
第1 章绪论5.选择题:C CBDCA6.试分析下面各程序段的时间复杂度。
(1)O(1)(2)O(m*n)(3)O(n2)(4)O(log3n)O(n (5)因为x++ 共执行了n-1+n-2+⋯⋯+1= n(n-1)/2 ,所以执行时间为2)(6)O( n )第2 章线性表1.选择题babadbcabdcddac2.算法设计题(6)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。
ElemType Max (LinkList L ){if(L->next==NULL) return NULL;pmax=L->next; // 假定第一个结点中数据具有最大值p=L->next->next;while(p != NULL ){// 如果下一个结点存在if(p->data > pmax->data) pmax=p;p=p->next;}return pmax->data;原表(7)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用的存储空间。
void inverse(LinkList &L) {// 逆置带头结点的单链表Lp=L->next; L->next=NULL;while ( p) {q=p->next; // q 指向*p 的后继p->next=L->next;L->next=p; // *p 插入在头结点之后p = q;}}(10)已知长度为n 的线性表 A 采用顺序存储结构,请写一时间复杂度为O (n) 、空间复杂度为O (1) 的算法,该算法删除线性表中所有值为item 的数据元素。
[ 题目分析] 在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i 个元素,第i+1 至第n 个元素要依次前移)。
本题要求删除线性表中所有值为item 的数据元素,并未要求元素间的相对位置不变。
第1章绪论5.选择题:CCBDCA6.试分析下面各程序段的时间复杂度。
(1)O(1)(2)O(m*n)(3)O(n2)(4)O(log3n)(5)因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O(n2)(6)O(n)第2章线性表1.选择题babadbcabdcddac2.算法设计题(6)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。
ElemType Max (LinkList L ){if(L->next==NULL) return NULL;pmax=L->next; //假定第一个结点中数据具有最大值p=L->next->next;while(p != NULL ){//如果下一个结点存在if(p->data > pmax->data) pmax=p;p=p->next;}return pmax->data;(7)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。
void inverse(LinkList &L) {// 逆置带头结点的单链表 Lp=L->next; L->next=NULL;while ( p) {q=p->next; // q指向*p的后继p->next=L->next;L->next=p; // *p插入在头结点之后p = q;}}(10)已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。
[题目分析] 在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。
本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。
因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。
/computer/book/read/data-structure/h971111102.html 习题解答(唐策善版)(其他版本在上面)第一章绪论(参考答案)1.3 (1) O(n)(2)(2)O(n)(3)(3)O(n)(4)(4)O(n1/2)(5)(5)执行程序段的过程中,x,y值变化如下:循环次数x y0(初始)91 1001 92 1002 93 100………………9 100 10010 101 10011 91 9912 92 100………………20 101 9921 91 98………………30 101 9831 91 97到y=0时,要执行10*100次,可记为O(10*y)=O(n)1.5 2100 , (2/3)n , log2n , n1/2 ,n3/2, (3/2)n , n log2n , 2 n ,n! , n n第二章线性表(参考答案)在以下习题解答中,假定使用如下类型定义:(1)顺序存储结构:#define MAXSIZE 1024typedef int ElemType;// 实际上,ElemType可以是任意类型typedef struct{ ElemType data[MAXSIZE];int last; // last表示终端结点在向量中的位置}sequenlist;(2)链式存储结构(单链表)typedef struct node{ElemType data;struct node *next;}linklist;(3)链式存储结构(双链表)typedef struct node{ElemType data;struct node *prior,*next;}dlinklist;(4)静态链表typedef struct{ElemType data;int next;}node;node sa[MAXSIZE];2.1 头指针:指向链表的指针。
因为对链表的所有操均需从头指针开始,即头指针具有标识链表的作用,所以链表的名字往往用头指针来标识。
如:链表的头指针是la,往往简称为“链表la”。
头结点:为了链表操作统一,在链表第一元素结点(称为首元结点,或首结点)之前增加的一个结点,该结点称为头结点,其数据域不无实际意义(当然,也可以存储链表长度,这只是副产品),其指针域指向头结点。
这样在插入和删除中头结点不变。
开始结点:即上面所讲第一个元素的结点。
2.2 只设尾指针的单循环链表,从尾指针出发能访问链表上的任何结点。
2·3void insert(ElemType A[],int elenum,ElemType x)// 向量A目前有elenum个元素,且递增有序,本算法将x插入到向量A中,并保持向量的递增有序。
{ int i=0,j;while (i<elenum && A[i]<=x) i++; // 查找插入位置for (j= elenum-1;j>=i;j--) A[j+1]=A[j];// 向后移动元素A[i]=x; // 插入元素} // 算法结束2·4void rightrotate(ElemType A[],int n,k)// 以向量作存储结构,本算法将向量中的n个元素循环右移k位,且只用一个辅助空间。
{ int num=0; // 计数,最终应等于nint start=0; // 记录开始位置(下标)while (num<n){ temp=A[start]; //暂存起点元素值,temp与向量中元素类型相同empty=start; //保存空位置下标next=(start-K+n) %n; // 计算下一右移元素的下标while (next !=start){ A[empty]=A[next];// 右移num++; // 右移元素数加1empty=next;next=(next-K+n) %n; // 计算新右移元素的下标}A[empty]=temp; // 把一轮右移中最后一个元素放到合适位置num++;start++; // 起点增1,若num<n则开始下一轮右移。
}} // 算法结束算法二算法思想:先将左面n-k个元素逆置,接着将右面k个元素逆置,最后再将这n个元素逆置。
void rightrotate(ElemType A[],int n,k)// 以向量作存储结构,本算法将向量中的n个元素循环右移k位,且只用一个辅助空间。
{ ElemType temp;for(i=0;i<(n-k)/2;i++) //左面n-k个元素逆置{temp=A[i]; A[i]=A[n-k-1-i]; A[n-k-1-i]=temp; }for(i=1;i<=k;i++) //右面k个元素逆置{temp=A[n-k-i]; A[n-k-i]=A[n-i]; A[n-i]=temp; }for(i=0;i<n/2;i++) //全部n个元素逆置{temp=A[i]; A[i]=A[n-1-i]; A[n-1-i]=temp; }} // 算法结束2·5void insert(linklist *L,ElemType x)// 带头结点的单链表L递增有序,本算法将x插入到链表中,并保持链表的递增有序。
{ linklist *p=L->next, *pre=L,*s;// p为工作指针,指向当前元素,pre为前驱指针,指向当前元素的前驱s=(linklist *)malloc(sizeof(linklist));//申请空间,不判断溢出s->data=x;while (p && p->data<=x) {pre=p; p=p->next;} // 查找插入位置pre->next=s; s->next=p; // 插入元素} // 算法结束2·6void invert(linklist *L)// 本算法将带头结点的单链表L逆置。
//算法思想是先将头结点从表上摘下,然后从第一个元素结点开始,依次前插入以L为头结点的链表中。
{ linklist *p=L->next,*s;// p为工作指针,指向当前元素,s为p的后继指针L->next=null;//头结点摘下,指针域置空。
算法中头指针L始终不变while (p){s=p->next; // 保留后继结点的指针p->next=L->next; // 逆置L->next=p;p=s; // 将p指向下个待逆置结点}} // 算法结束2·7(1) int length1(linklist *L)// 本算法计算带头结点的单链表L的长度{ linklist *p=L->next; int i=0;// p为工作指针,指向当前元素,i 表示链表的长度while (p){ i++; p=p->next; }return(i);} // 算法结束(2) int length1(node sa[MAXSIZE])// 本算法计算静态链表s中元素的个数。
{ int p=sa[0].next, i=0;// p为工作指针,指向当前元素,i 表示元素的个数,静态链指针等于-1时链表结束while (p!=-1){ i++; p=sa[p].next; }return(i);} // 算法结束2·8void union_invert(linklist *A,*B,*C)// A和B是两个带头结点的递增有序的单链表,本算法将两表合并成// 一个带头结点的递减有序单链表C,利用原表空间。
{ linklist *pa=A->next,*pb=B->next,*C=A,*r;// pa,pb为工作指针,分别指向A表和B表的当前元素,r为当前逆置//元素的后继指针, 使逆置元素的表避免断开。
//算法思想是边合并边逆置,使递增有序的单链表合并为递减有序的单链表。
C->next=null;//头结点摘下,指针域置空。
算法中头指针C始终不变while (pa && pb) // 两表均不空时作if (pa->data<=pb->data) // 将A表中元素合并且逆置{ r=pa->next; // 保留后继结点的指针pa->next=C->next; // 逆置C->next=pa;pa=r; // 恢复待逆置结点的指针}else // 将B表中元素合并且逆置{ r=pb->next; // 保留后继结点的指针pb->next=C->next; // 逆置C->next=pb;pb=r; // 恢复待逆置结点的指针}// 以下while (pa)和while (pb)语句,只执行一个while (pa) // 将A表中剩余元素逆置{ r=pa->next; // 保留后继结点的指针pa->next=C->next; // 逆置C->next=pa;pa=r; // 恢复待逆置结点的指针}while (pb) // 将B表中剩余元素逆置{ r=pb->next; // 保留后继结点的指针pb->next=C->next; // 逆置C->next=pb;pb=r; // 恢复待逆置结点的指针}free(B);//释放B表头结点} // 算法结束2·9void deleteprior(linklist *L)// 长度大于1的单循环链表,既无头结点,也无头指针,本算法删除*s 的前驱结点{ linklist *p=s->next,*pre=s; // p为工作指针,指向当前元素,// pre为前驱指针,指向当前元素*p的前驱while (p->next!=s) {pre=p; p=p->next;} // 查找*s的前驱pre->next=s;free(p); // 删除元素} // 算法结束2·10void one_to_three(linklist *A,*B,*C)// A是带头结点的的单链表,其数据元素是字符字母、字符、数字字符、其他字符。
本算法//将A表分成// 三个带头结点的循环单链表A、B和C,分别含有字母、数字和其它符号的同一类字符,利用原表空间。
{ linklist *p=A->next,r;// p为工作指针,指向A表的当前元素,r为当前元素的后继指针,使表避免断开。