资源描述
十二五普通高等教育国家级本科规划教材
第 1 章
绪论
高等学校精品资源共享课程
1、1 什么就是数据结构?
【答】:数据结构就是指按一定得逻辑结构组成得一批数据,使用某种存储结构将这批数据存储
于计算机中,并在这些数据上定义了一个运算集合.
1、2 数据结构涉及哪几个方面?
【答】:数据结构涉及三个方面得内容,即数据得逻辑结构、数据得存储结构与数据得运算集
合.
1、3 两个数据结构得逻辑结构与存储结构都相同,但就是它们得运算集合中有一个运算得定义不
一样,它们就是否可以认作就是同一个数据结构?为什么?
【答】:不能,运算集合就是数据结构得重要组成部分,不同得运算集合所确定得数据结构就是不
一样得,例如,栈与队列它们得逻辑结构与存储结构可以相同,但由于它们得运算集合不一样,
所以它们就是两种不同得数据结构。
1、4 线性结构得特点就是什么?非线性结构得特点就是什么?
【答】:线性结构元素之间得关系就是一对一得,在线性结构中只有一个开始结点与一个终端结
点,其她得每一个结点有且仅有一个前驱与一个后继结点。而非线性结构则没有这个特点,元
素之间得关系可以就是一对多得或多对多得.
1、5 数据结构得存储方式有哪几种?
【答】:数据结构得存储方式有顺序存储、链式存储、散列存储与索引存储等四种方式.
1、6 算法有哪些特点?它与程序得主要区别就是什么?
【答】:算法具有(1)有穷性(2)确定性(3)0 个或多个输入(4)1 个或多个输出(5)可
行性等特征。程序就是算法得一种描述方式,通过程序可以在计算机上实现算法。
1、7 抽象数据类型得就是什么?它有什么特点?
【答】:抽象数据类型就是数据类型得进一步抽象,就是大家熟知得基本数据类型得延伸与发展.
抽象数据类型就是与表示无关得数据类型,就是一个数据模型及定义在该模型上得一组运算。对一
个抽象数据类型进行定义时,必须给出它得名字及各运算得运算符名,即函数名,并且规定这
些函数得参数性质。一旦定义了一个抽象数据类型及具体实现,程序设计中就可以像使用基本
数据类型那样,十分方便地使用抽象数据类型。抽象数据类型得设计者根据这些描述给出操作
得具体实现,抽象数据类型得使用者依据这些描述使用抽象数据类型。
1、8 算法得时间复杂度指得就是什么?如何表示?
【答】:算法执行时间得度量不就是采用算法执行得绝对时间来计算得,因为一个算法在不同得
机器上执行所花得时间不一样,在不同时刻也会由于计算机资源占用情况得不同,使得算法在
同一台计算机上执行得时间也不一样,另外,算法执行得时间还与输入数据得状态有关,所以
对于算法得时间复杂性,采用算法执行过程中其基本操作得执行次数,称为计算量来度量.算
法中基本操作得执行次数一般就是与问题规模有关得,对于结点个数为 n 得数据处理问题,用
T(n)表示算法基本操作得执行次数。为了评价算法得执行效率,通常采用大写 O 符号表示算法
得时间复杂度,大写 O 符号给出了函数 f 得一个上限。其它义如下:
3
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
定义:f (n)=O (g (n)) 当且仅当存在正得常数 c 与 n0,使得对于所有得 n≥n0,有 f (n) ≤c g(n)。
上述定义表明,函数 f 顶多就是函数 g 得 c 倍,除非 n 小于 n0.因此对于足够大得 n (如 n≥n0),
g 就是 f 得一个上限(不考虑常数因子 c)。在为函数 f 提供一个上限函数 g 时,通常使用比较
简单得函数形式。比较典型得形式就是含有 n 得单个项(带一个常数系数)。表 1-1 列出了一些
常用得 g 函数及其名称。对于表 1-1 中得对数函数 logn,没有给出对数基,原因就是对于任何大
于 1 得常数 a 与 b 都有 logan =logbn/logba,所以 logan 与 logbn 都有一个相对得乘法系数 1/logba,
其中 a 就是一个常量。
表 1-1 常用得渐进函数
1、9 算法得空间复杂度指得就是什么?如何表示?
【答】:算法得空间复杂度就是指算法在执行过程中占用得额外得辅助空间得个数。可以将它表
示为问题规模得函数,并通过大写O符号表示空间复杂度。
1、10 对于下面得程序段,分析带下划线得语句得执行次数,并给出它们得时间复杂度 T(n)。
(1) i++ ;
(2) for(i=0;i〈n;i++)
if (a[i]<x) x=a[i];
(3)for(i=0;i<n;i++)
for(j=0;j〈n;j++)
printf(“%d”,i+j) ;
(4)for (i=1;i<=n—1;i++)
{ k=i;
for(j=i+1;j〈=n;j++)
if(a[j]>a[j+1]) k=j;
t=a[k]; a[k]=a[i]; a[i]=t;
}
(5)for(i=0;i<n;i++)
for(j=0;j<n;j++)
{++x;s=s+x;}
【答】:(1)O(1);(2)O(n);(3)O(n2);(4)O(n2);(5)O(n2)
4
函数
名称
1
logn
n
nlogn
2
n
3
n
n
2
n!
常数
对数
线性
n 个 logn
平方
立方
指数
阶乘
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
第 2 章
线性表及其顺序存储
2、1 选择题
(1)表长为 n 得顺序存储得线性表,当在任何位置上插入或删除一个元素得概率相等时,
插入一个元素所需移动元素得平均个数为(
为( A )。
E
ﻮ),删除一个元素所需移动元素得平均个数
A.(n−1)/2
E.n/2
ﻮB。n
F.(n+1)/2
ﻮC.n+1
G.(n−2)/2
ﻮD.n−1
(2)设栈 S 与队列 Q 得初始状态为空,元素 e1、e2、e3、e4、e5 与 e6 依次通过栈 S,
一个元素出栈后即进入队列 Q,若 6 个元素出队得序列为 e2、e4、e3、e6、e5 与 e1,则栈 S
得容量至少应该为( C )。
A。6
ﻮB。4
C.3
D.2
(3)设栈得输入序列为 1、2、3… n,若输出序列得第一个元素为 n,则第 i 个输出得元素为
( B ).
A.不确定
B.n−i+1
ﻮC.i
ﻮD。n−i
(4)在一个长度为 n 得顺序表中删除第 i 个元素(1<=i<=n)时,需向前移动( A )个
元素。
A.n−i
B。n−i+1
ﻮC.n−i−1
ﻮD。i
(5)若长度为 n 得线性表采用顺序存储结构存储,在第 i 个位置上插入一个新元素得时
间复杂度为( A ).
A。O(n)
B.O(1)
C.O(n2)
ﻮD.O(n3)
(6)表达式 a*(b+c)−d 得后缀表达式就是( B
ﻮ)。
A.abcd*+−
ﻮB.abc+*d−
C.abc*+d−
ﻮD。−+*abcd
(7)队列就是一种特殊得线性表,其特殊性在于( C ).
A.插入与删除在表得不同位置执行 B。插入与删除在表得两端位置执行
C.插入与删除分别在表得两端执行 D。插入与删除都在表得某一端执行
(8)栈就是一种特殊得线性表,具有( B )性质。
A.先进先出
ﻮB.先进后出
ﻮC。后进后出
D。顺序进出
(9)顺序循环队列中(数组得大小为 n),队头指示 front 指向队列得第 1 个元素,队尾
指示 rear 指向队列最后元素得后 1 个位置,则循环队列中存放了 n − 1 个元素,即循环队列满
得条件为( B
)。
A。(rear+1)%n=front−1
C。(rear)%n=front
B.(rear+1)%n=front
D。rear+1=front
(10)顺序循环队列中(数组得大小为 6),队头指示 front 与队尾指示 rear 得值分别为 3
与 0,当从队列中删除 1 个元素,再插入 2 个元素后,front 与 rear 得值分别为( D )。
A.5 与 1
ﻮB。2 与 4
C.1 与 5
D。4 与 2
2、2 什么就是顺序表?什么就是栈?什么就是队列?
5
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
【答】:当线性表采用顺序存储结构时,即为顺序表。栈就是一种特殊得线性表,它得特殊性表
现在约定了在这种线性表中数据得插入与删除操作只能在这种线性表得同一端进行(即栈顶),
因此,栈具有先进后出、后进先出得特点.队列也就是一种特殊得线性表,它得特殊性表现在约
定了在这种线性表中数据得插入在表得一端进行,数据得删除在表得另一端进行,因此队列具
有先进先出,后进后出得特点。
2、3 设计一个算法,求顺序表中值为 x 得结点得个数。
【答】:顺序表得存储结构定义如下(文件名 seqlist、h):
#include 〈stdio、h〉
#define N 100
typedef int datatype;
typedef struct {
datatype data[N];
int length;
} seqlist;
ﻮ/*预定义最大得数据域空间*/
/*假设数据类型为整型*/
/*此处假设数据元素只包含一个整型得关键字域*/
/*线性表长度*/
/*预定义得顺序表类型*/
算法 countx(L,x)用于求顺序表 L 中值为 x 得结点得个数。
int countx(seqlist *L,datatype x)
{
int c=0;
int i;
for (i=0;i〈L->length;i++)
if (L—>data[i]==x) c++;
return c;
}
2、4 设计一个算法,将一个顺序表倒置。即,如果顺序表各个结点值存储在一维数组 a 中,倒
置得结果就是使得数组 a 中得 a[0]等于原来得最后一个元素,a[1] 等于原来得倒数第 2 个元
素,…,a 得最后一个元素等于原来得第一个元素。
【答】:顺序表得存储结构定义同题 2、3,实现顺序表倒置得算法程序如下:
void verge(seqlist *L)
{int t,i,j;
i=0;
j=L->length-1;
while (i〈j)
{ t=L->data[i];
L-〉data[i++]=L—>data[j];
L->data[j—-]=t;
}
}
2、5 已知一个顺序表中得各结点值就是从小到大有序得,设计一个算法,插入一个值为 x 得结点,
使顺序表中得结点仍然就是从小到大有序.
【答】:顺序表得定义同题 2、3,实现本题要求得算法程序如下:
6
十二五普通高等教育国家级本科规划教材
void insertx(seqlist *L,datatype x)
{int j;
if (L-〉length〈N)
{ j=L—〉length-1;
while (j〉=0 && L—>data[j]>x)
{ L->data[j+1]=L-〉data[j];
j--;
}
L—>data[j+1]=x;
L—〉length++;
}
}
2、6 将下列中缀表达式转换为等价得后缀表达式。
(1) 5+6*7
(2) (5—6)/7
(3) 5—6*7*8
(4) 5*7—8
(5) 5*(7-6)+8/9
(6) 7*(5-6*8)—9
【答】:
高等学校精品资源共享课程
(7) 5+6*7
(8) (5—6)/7
(9) 5-6*7*8
(10)5*7-8
(11)5*(7-6)+8/9
(12)7*(5-6*8)-9
后缀表达式:5 6 7*+
后缀表达式:5 6-7/
后缀表达式:5 6 7*8*—
后缀表达式:5 7* 8-
后缀表达式:5 7 6—*8 9/+
后缀表达式:7 5 6 8*-*9—
2、7 循环队列存储在一个数组中,数组大小为 n,队首指针与队尾指针分别为 front 与 rear,请
写出求循环队列中当前结点个数得表达式。
【答】:循环队列中当前结点个数得计算公式就是:(n+rear-front)%n
2、8 编号为 1,2,3,4 得四列火车通过一个栈式得列车调度站,可能得到得调度结果有哪些?如果
有 n 列火车通过调度站,请设计一个算法,输出所有可能得调度结果。
【答】:
方法一:
算法思想:逐次输出所有可能,用回溯法。即:
总体:对原始序列中得每一个元素,总就是先入栈,后出栈
1。入栈后得操作:a、该元素出栈;b、下一个元素入栈;
2.出栈后得操作:a、(栈中其她元素)继续出栈;b、 (原始序列中)下一个数入栈;
注意:回溯法,关键在于回溯,即在某分支结点 X:处理 X 得一个子分支,再退回分支 X,
接着处理 X 得下一个子分支,若所有 X 得子分支处理完,再退回上一层分支节点。所谓“退回”,
7
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
实际上就就是恢复。
程序代码:(2_8_1、c)
#include <stdio、h〉
#define MAX 26
typedef struct s{
char a[MAX];
int top;
}Stack;
/*定义一些全局变量*/
Stack S; /*定义全局性得栈*/
char d[MAX],seq[MAX]; /*d[MAX]用于存储原始入栈序列,seq[MAX]用于存储输出序列*/
int len; /*定义将通过栈得元素个数*/
int count=0; /* 用于统计输出序列得个数 */
void initStack(Stack *S) /*初始化空栈*/
{ S—>top=-1; }
void push(Stack *S, char x) /*进栈*/
{
if (S->top>=MAX) return;
S->top++;
S—〉a[S->top]=x;
}
char pop(Stack *S)/*出栈*/
{
ﻮif (S—〉top==—1)
{ printf("ERROR, POP Empty Stack”);
return —1;
}
S->top--;
return S-〉a[S-〉top+1];
}
int isEmpty(Stack *S)/*判断栈就是否为空*/
{
if (S-〉top==-1) return 1;
return 0;
}
void outSeq(char *seq, int len)/*输出顶点序列*/
{
int i;
for(i=0; i〈len; i++)
printf(”%2c",seq[i]);
printf("\n");
}
void scheduler(int pos, int seq_pos)
8
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
{
/*
pos: 处理到原始数据中得第 pos 个元素,
seq_pos:若出栈,应放在当前输出数组得第 seq_pos 个位置
*/
int i=0;char t;
/*对任何一个数,总就是先进栈,再出栈。另外,这里不需要循环,类似于“查找数组中元
素”用递归*/
if(pos〈len){/*一个数进栈后,有两种处理方式:要么立刻出栈,要么进行下一个数得进栈*/
push(&S,d[pos]);
scheduler(pos+1,seq_pos);
pop(&S);
}
if (!isEmpty(&S)){/*一个数出栈后,有两种处理方式:要么继续出栈,要么继续下一个数得进
栈*/
t=pop(&S);
seq[seq_pos++]=t;
scheduler(pos,seq_pos);
push(&S,t);
}
if (pos>=len && isEmpty(&S))
{ outSeq(seq,len); count++; }
}
int main(){
int i;
printf(”\nplease input the num be scheduled: ");
scanf(”%d”, &len); /*用 len 存储待调度得火车数量*/
for(i=0; i〈len; i++)
d[i]='a'+i; /*创建火车编号,如 a、b、c、、、、等*/
printf(”the original seq is:”);
outSeq(d,len);
initStack(&S);
scheduler(0,0);
printf("\n count=%5d”, count);
return 0;
}
方法二:
解题思路:栈具有先进后出、后进先出得特点,因此,任何一个调度结果应该就是 1,2,3,
4 全排列中得一个元素。由于进栈得顺序就是由小到大得,所以出栈序列应该满足以下条件:对
于序列中得任何一个数其后面所有比它小得数应该就是倒序得,例如 4321 就是一个有效得出栈序
9
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
列,1423 不就是一个有效得出栈结果(4 后面比它小得两个数 2,3 不就是倒序)。据此,本题可以
通过算法产生 n 个数得全排列,然后将满足出栈规则得序列输出.
产生 n 个数得全排列有递归与非递归两种实现算法.
产生全排列得递归算法:
设 R={r1,r2,…,rn}就是要进行排列得 n 个元素,Ri=R-{ri}。集合 X 中元素得全排列记为
perm(X)。(ri)perm(X)表示在全排列 perm(X)得每一个排列前加上前缀 ri 得到得排列。R 得全排
列可归纳定义如下:
当 n=1 时,perm(R)=(r),其中 r 就是集合 R 中惟一得元素;
当 n>1 时,perm(R)由(r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn)构成。
依此递归定义,可设计产生 perm(R)得递归算法如下:
递归解法:(2_8_2、c)
#include<stdio、h>
int cont=1;
ﻮ/*全局变量,用于记录所有可能得出栈序列个数*/
void print(int str[],int n);
/*求整数序列 str[]从 k 到 n 得全排列*/
void perm(int str[],int k,int n)
{int i,temp;
if (k==n-1) print(str,n);
else
{ for (i=k;i〈n;i++)
{temp=str[k]; str[k]=str[i]; str[i]=temp;
perm(str,k+1,n); /*递归调用*/
temp=str[i]; str[i]=str[k]; str[k]=temp;
}
}
}
/*本函数判断整数序列 str[]就是否满足进出栈规则,若满足则输出*/
void print(int str[],int n)
{int i,j,k,l,m,flag=1,b[2];
for(i=0;i<n;i++)
ﻮ/*对每个 str[i]判断其后比它小得数就是否为降序序列*/
{ m=0;
for(j=i+1;j<n&&flag;j++)
if (str[i]>str[j]) {if (m==0) b[m++]=str[j];
else {if (str[j]〉b[0]) {flag=0;}
else b[0]=str[j];
}
}
}
if(flag)
ﻮ/*满足出栈规则则输出 str[]中得序列*/
10
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
{
printf(” %2d:",cont++);
for(i=0;i<n;i++)
printf("%d”,str[i]);
printf("\n");
}
}
int main()
{int str[100],n,i;
printf("input a int:"); /*输出排列得元素个数*/
scanf("%d",&n);
for(i=0;i<n;i++) /*初始化排列集合*/
str[i]=i+1;
printf("input the result:\n");
perm(str,0,n);
printf("\n");
return 0;
}
当参与进出栈得元素个数为 4 时,输出得结果如下图所示.
该算法执行得时间复杂度为 O(n!)。随着 n 得增大,算法得执行效率非常得低。
非递归解法:(2_8_3、c)
对一组数穷尽所有排列,还可一种更直接得方法,将一个排列瞧作一个长整数,则所有排
列对应着一组整数,将这组整数按从小到大得顺序排成一个数列,从对应最小得整数开始,按
数列得递增顺序逐一列举每个排列对应得每一个整数,这能更有效地完成排列得穷举。从一个
排列找出对应数列得下一个排列可在当前排列得基础上作部分调整来实现。倘若当前排列为
1,2,4,6,5,3,并令其对应得长整数为 124653。要寻找比长整数 124653 更大得排列,可从该排列
得最后一个数字顺序向前逐位考察,当发现排列中得某个数字比它前一个数字大时,如本例中
得 6 比它得前一位数字 4 大,则说明还有可能对应更大整数得排列.但为顺序从小到大列举出
所有得排列,不能立即调整得太大,如本例中将数字 6 与数字 4 交换得到得排列为 126453 就
不就是排列 124653 得下一个排列。为得到排列 124653 得下一个排列,应从已考察过得那部分数
11
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
字中选出比数字 4 大,但又就是它们中最小得那一个数字,比如数字 5,与数字 4 交换.该数字
也就是从后向前考察过程中第一个比 4 大得数字,5 与 4 交换后,得到排列 125643。在前面数字
1,2,5 固定得情况下,还应选择对应最小整数得那个排列,为此还需将后面那部分数字得排
列颠倒,如将数字 6,4,3 得排列顺序颠倒,得到排列 1,2,5,3,4,6,这才就是排列 1,2,4,6,
5,3 得下一个排列。按照以上想法可以编写非递归程序实现 n 个数得全排列,对满足进出栈
规则得排列则计数并输出。
/*本程序输出 1 2 、、、 n 个序列进栈出栈得序列*/
#include 〈stdio、h>
int pl(int n)
{ int a[100];
int flag=1,flag1=0;
FILE *rf ;
int i,j,k,x,count=0;
rf = fopen("stack、txt", ”w") ;
for (i=1;i〈=n;i++)
a[i]=i;
while (flag)
{ flag1=1;
ﻮ/*最大处理范围为 99 个数*/
/*pl、txt 用于存放进出栈序列结果*/
/*初始序列*/
/* 还剩余未输出得排列*/
/* 判断本次排列就是否符合进栈出栈序列 */
for (i=1;i<=n;i++)
{ j=i+1;
while (j<=n && a[j]>a[i]) j++; /* 找 a[i]后第一个比 a[i]小得元素 a[j]*/
k=j+1;
while (k〈=n)
ﻮ/* 如果 a[j]后还有比 a[i]小且比 a[j]大得元素,则此排列无效*/
{if ( a[k] <a[i] && a[k]>a[j]) flag1=0;
k++;
}
}
if (flag1)
{ for (i=1;i<=n;i++)
/*输出当前排列*/
{ printf("%4d",a[i]); fprintf(rf,”%4d”,a[i]);}
printf("\n"); fprintf(rf,”\n”);
count++;
}
i=n;
ﻮ/*计数器加 1*/
/*从后向前找相邻位置后大前小得元素值*/
while (i〉1 && a[i]〈a[i-1]) i—-;
if (i==1) flag=0; /*未找到则结束*/
else
{j=i—1;i=n;/* 若找到,则在该位置得后面从右向左找第一个比该元素大得值*/
while (i〉j && a[i]<a[j]) i--;
12
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
k=a[j];
a[j]=a[i];
a[i]=k;
k=j+1;
for ( i=k+1;i〈=n;i++)
/*交换两元素得值*/
/*对交换后后面得数据由小到大排序*/
/*插入排序*/
{j=i-1;
x=a[i];
while (j〉=k && x<a[j]) { a[j+1]=a[j]; j--;}
a[j+1]=x;
}
}
}
fclose(rf);
return count;
}
void main()
{int n,m=0;
/*返回排列总个数*/
printf("please input n:”);
scanf("%d",&n);
m=pl(n);
printf(”\nm=%d”,m);
ﻮ/*输入排列规模*/
/*输出满足进出栈得排列总个数*/
}
程序运行时如果输入 4,则输出得结果如下图所示。
该算法得时间复杂度也就是 O(n!)。
结论:如果 n 个数按编号由小到大得顺序进栈,进栈得过程中可以出栈,则所有可能得出栈序
列得总数为:
(2n)!
(n + 1)n!n!
13
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
第 3 章
线性表得链式存储
3、1 选择题
(1)两个有序线性表分别具有 n 个元素与 m 个元素且 n≤m,现将其归并成一个有序表,
其最少得比较次数就是( A )。
A.n
ﻮB.m
ﻮC。n−1
ﻮD。m+n
(2)非空得循环单链表 head 得尾结点(由 p 所指向)满足( C
)。
A。p—〉next==NULL B。p==NULL C.p—>next==head
ﻮD.p==head
(3)在带头结点得单链表中查找 x 应选择得程序体就是( C ).
A.node *p=head—>next; while (p && p->info!=x) p=p—〉next;
if (p->info==x)
return p else return NULL;
B.node *p=head; while (p&& p-〉info!=x) p=p-〉next; return p;
C.node *p=head->next;
ﻮwhile (p&&p->info!=x) p=p->next; return p;
D.node *p=head; while (p-〉info!=x) p=p—>next ; return p;
(4)线性表若采用链式存储结构时,要求内存中可用存储单元得地址( D )。
A。必须就是连续得
C.一定就是不连续得
ﻮB。部分地址必须就是连续得
D.连续不连续都可以
(5)在一个具有 n 个结点得有序单链表中插入一个新结点并保持单链表仍然有序得时间
复杂度就是( B
)。
A。O(1)
ﻮB.O(n)
C.O(n2)
ﻮD。O(nlog2n)
(6)用不带头结点得单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队
尾结点,则在进行删除操作时( D ).
A。仅修改队头指针
C.队头、队尾指针都要修改
ﻮB。仅修改队尾指针
D.队头,队尾指针都可能要修改
(7)若从键盘输入 n 个元素,则建立一个有序单向链表得时间复杂度为( B )。
A。O(n)
ﻮB.O(n2)
ﻮC.O(n3)
ﻮD.O(n×log2n)
(8)下面哪个术语与数据得存储结构无关( D ).
A。顺序表
B.链表
ﻮC。散列表
ﻮD.队列
(9)在一个单链表中,若删除 p 所指结点得后续结点,则执行( A )。
A。p->next=p-〉next-〉next;
C。p->next=p->next;
ﻮB.p=p-〉next; p-〉next=p->next—>next;
D.p =p—>next->next;
(10)在一个单链表中,若 p 所指结点不就是最后结点,在 p 之后插入 s 所指结点,则执行( B ).
A.s-〉next=p;p-〉next=s;
C.s—>next=p->next;p=s;
B.s->next=p-〉next;p->next=s;
D.p—〉next=s;s—>next=p;
3、2 设计一个算法,求一个单链表中得结点个数。
【答】:单链表存储结构定义如下(相关文件:linklist、h)
#include 〈stdlib、h〉
14
十二五普通高等教育国家级本科规划教材
#include <stdio、h>
typedef struct node
{ int data;
struct node *next;
}linknode;
typedef linknode *linklist;
/*尾插法创建带头结点得单链表*/
linklist creatlinklist()
{ linklist head,r,s;
int x;
head=r=(linklist)malloc(sizeof(linknode));
printf("\n 请输入一组以 0 结束得整数序列:\n”);
scanf("%d",&x);
while (x)
{ s=(linklist)malloc(sizeof(linknode));
s—〉data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return head;
}
/*输出带头结点得单链表*/
void print(linklist head)
{ linklist p;
p=head->next;
printf(”List is:\n”);
while(p)
{ printf("%5d”,p—>data);
p=p-〉next;
}
printf("\n");
}
基于上述结构定义,求单链表中得结点个数得算法程序如下:
int count(linklist head)
高等学校精品资源共享课程
{
ﻮint c=0;
linklist p=head;
while (p)
15
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
{c++;
p=p->next;
}
return c;
}
3、3 设计一个算法,求一个带头结点单链表中得结点个数。
【答】:带头结点得单链表得存储结构定义同题 3、2,实现本题功能得算法程序如下(3_3、c)
#include "linklist、h"
int count(linklist head)
{ int c=0;
linklist p=head—>next;
while (p)
{c++;
p=p->next;
}
return c;
}
main()
/*测试函数*/
{linklist head;
head=creatlinklist();
print(head);
printf(”\nLength of head is:%d",count(head));
getch();
}
当输入 5 个数据时,产生得输出结果如下图所示:
3、4 设计一个算法,在一个单链表中值为 y 得结点前面插入一个值为 x 得结点.即使值为 x 得
新结点成为值为 y 得结点得前驱结点。
【答】:
#include ”linklist、h”
void insert(linklist head,int y,int x)
{/*在值为 y 得结点前插入一个值为 x 得结点*/
linklist pre,p,s;
pre=head;
16
}
十二五普通高等教育国家级本科规划教材
p=head->next;
while (p && p->data!=y)
{ pre=p;
p=p-〉next;
}
if (p)/*找到了值为 y 得结点*/
{ s=(linklist)malloc(sizeof(linknode));
s—〉data=x;
s->next=p;
pre-〉next=s;
}
高等学校精品资源共享课程
void main()
{linklist head;
int y,x;
head=creatlinklist();
print(head);
/*测试程序*/
/*创建单链表*/
/*输出单链表*/
printf("\n 请输入 y 与 x 得值:\n”);
scanf("%d %d",&y,&x);
insert(head,y,x);
print(head);
}
程序得一种运行结果如下图所示:
3、5 设计一个算法,判断一个单链表中各个结点值就是否有序.
【答】:
#include "linklist、h"
int issorted(linklist head,char c)
/*当参数 c=’a’时判断链表就是否为升序,当参数 c='d’就是判断链表就是否为降序*/
{ int flag=1;
linklist p=head-〉next;
switch (c)
17
}
十二五普通高等教育国家级本科规划教材
{case 'a':/*判断带头结点得单链表 head 就是否为升序*/
while (p &&p—>next && flag)
{if (p—>data〈=p->next—>data) p=p->next;
else flag=0;
}
break;
case 'd’:/*判断带头结点得单链表 head 就是否为降序*/
while (p &&p->next && flag)
{if (p—>data>=p—>next->data) p=p->next;
else flag=0;
}
break;
}
return flag;
高等学校精品资源共享课程
int main()
/*测试程序*/
{ linklist head;
head=creatlinklist();
print(head);
if (issorted(head,’a')) printf(”单链表 head 就是升序排列得!\n");
else
if (issorted(head,'d')) printf("单链表 head 就是降序排列得!\n");
展开阅读全文