数据结构实验

数据结构实验5

1、阅读以下算法,填充空格,使其成为完整的算法。其功能是在一个非递减的顺序存储线性表中,删除所有值相等的多余元素(参考源代码zuoye5_01.c)。

#include <stdio.h>
#define maxlen 30

typedef struct
{
		int elem[maxlen];
		int lenth;		//存放顺序表中元素个数
} sqlisttp;

void demo(sqlisttp *L)
{
	int i = 1, j = 0;
		while (i < L->lenth)       //当表不为空或只有一个数据
	{
		if (L->elem[i] != L->elem[j])     //如果第一个数据与第二个数据不同就将第一个数据保存在 elem[j], 相同则跳过,将不同的保存在elem[j]
		{
			j++;
			L->elem[j]=L->elem[i];
		}    
		i++;
	}
	
	L->lenth=j;
}

int main(void)
{
	int i;
	sqlisttp L;

	for (i = 0; i <= 15; i++)
	{
		L.elem[i] = i / 2;
	}
	L.lenth = i;
	for (i = 0; i <= L.lenth; i++)
	{
		printf("%d, ", L.elem[i]);
	}
   // printf("\n ");
	demo(&L);
	for (i = 0; i <= L.lenth; i++)
	{
		printf("%d, ", L.elem[i]);
	}
	printf("\n");
	return 0;
	
	
}




2、对于一个具有n个结点的单链表,在已知的结点p后插入一个新结点的时间复杂度为___O(1)_____,在给定值为x的结点后插入一个新结点的时间复杂度为____O(n)____。

3、在双向链表结构中,若要求在p指针所指的结点之前插入指针为s所指的结点,则需执行下列语句:

s->next = p;s->prior = _p->piror__;p->prior = s;__p->piror-next__ = s;

4、对于双向链表,在两个结点之间插入一个新结点需修改的指针共__4__个,单链表为___2___个。

5、已给如下关于单链表的类型说明:

typedef struct _list

{

int data;

struct _list *next;

} list;

以下程序采用链表合并的方法,将两个已排序的单链表合并成一个链表而不改变其排序性(升序),这里两链表的头指针分别为p和q(参考源代码zuoye5_05.c)。

#include <stdio.h>
#include <malloc.h>

typedef struct _list
{
	int data;
	struct _list *next;
} list;

void mergelink(list *p, list *q)
{
	list *h, *r;

	h = (list *)malloc(sizeof(list));
	h->next = NULL;    
	r = h;
	while (p != NULL && q != NULL)   
	{
		if (p->data <= q->data)       
		{
			r->next=p;
			r = p; 
			p = p->next;
		}
		else
		{
			r->next=q;
			r = q;
			q = q->next;
		}
	}
	if (p == NULL)
	{
		r->next = q;
	}
	else
	{
		r->next=p;
	}
	p = h->next;
	free(h);
}

void print(list *h)
{
	list *p;

	p = h;
	while (p != NULL)
	{
		printf("%d, ", p->data);
		p = p->next;
	}
	printf("\n");
}

int main(void)
{
	int i;
	list *h1, *h2;
	list *p1, *q1, *p2, *q2;

	h1 = q1 = p1 = (list *)malloc(sizeof(list));
	h2 = q2 = p2 = (list *)malloc(sizeof(list));
	h1->data = 1;
	h2->data = 1;
	h1->next = NULL;
	h2->next = NULL;
	for (i = 1; i <= 10; i++)
	{
		p1 = (list *)malloc(sizeof(list));
		p2 = (list *)malloc(sizeof(list));
		
		p1->data = i * 2;
		p2->data = i * 3;
		
		p1->next = q1->next;
		q1->next=p1;
		q1 = p1;
		p2->next = q2->next;
		q2->next=p2;
		q2 = p2;
	}
	print(h1);
	print(h2);

	mergelink(h1, h2);

	print(h1);
	return 0;


}











6、设pa,pb分别指向两个带头结点的有序(从小到大)单链表。仔细阅读如下的程序,并回答问题:

(1)程序的功能;

(2)s1,s2中值的含义;

(3)pa,pb中值的含义。

void exam(list *pa, list *pb)

{

list *p, *p1, *p2;

int s1, s2;

p1 = pa->next;//

p2 = pb->next;

pa->next = NULL;

s1 = 0;

s2 = 0;

while (p1 != NULL && p2 != NULL)

{

if (p1->data < p2->data)

{

p = p1;

p1 = p1->next;

s2++;

free(p);

}

else if (p1->data > p2->data)

{

p2 = p2->next;

}

else

{

p = p1;

p1 = p1->next;

p->next = pa->next;

pa->next = p;

p2 = p2->next;

s1++;

}

}

while (p1 != NULL)

{

p = p1;

p1 = p1->next;

free(p);

s2++;

}

}

答:(1)程序的功能是将pa链表中与pb中相同的元素留下来(删除其它不同元素),并倒序存放;

(2)s1中存放的是pa中与pb中相同元素的个数,s2中存放pa中被删除元素的个数(即与pb不同的元素的个数)

(3)pa中值是地址值,存放其中一个头结点的地址,pb中值同pa(存放另一个地址)。

7、已知L是一个数据类型linkedlist的单循环链表,pa和pb是指向L中结点的指针。简述下列程序段的功能(参考源代码zuoye5_07.c)。

typedef struct _linklist

{

int data;

struct _linklist *next;

} linklist;

void subp(linklist *s, linklist *q)

{

linklist *p;

p = s;

while (p->next != q)

{

p = p->next;

}

p->next = s;

}

void Mp(linklist *pa, linklist *pb)

{

subp(pa, pb);

subp(pb, pa);

}

答:该Mp函数功能是将pa所指结点到pb前一个结点的这些结点形成一个循环链表(pa是入口),将pb所指结点到pa前一个结点的结点形成另一个循环链表(pb是入口)。

8、表达式23+((12*3-2)/4+34*5/7)+108/9的后缀表达式是_23 12 3*2-4/34 5*7/++108 9 /+_。

9、栈是________的线性表,其运算遵循_先出后进_的原则。队列是________的线性表,其运算遵循________的原则。

操作受限   后进先出          允许一端插入一段删除      先进先出

10、一个栈的输入序列是:1,2,3则不可能的栈输出序列是________。

3,1,2

11、设有一个空栈,栈顶指针为1000H(十六进制),现有输入序列为1,2,3,4,5,经过PUSH,PUSH,POP,PUSH,POP,PUSH,PUSH之后,输出序列是________,而栈顶指针值是________H。设栈为顺序栈,每个元素占4个字节。

两个pop   分别 2 3   100C

12、设输入序列为2,3,4,5,6,利用一个栈能得到序列2,5,3,4,6吗?栈可以用单链表实现吗?    不能     栈可以使用单链表实现,将单链表的表头作为栈底。

13、设循环队列用数组A[1..M]表示,队首、队尾指针分别是FRONT和TAIL,判定队满的条件为_(TAIL+1)%M==FRONT%M_。

14、设Q[0..N-1]为循环队列,其头、尾指针分别为P和R,则队Q中当前所含元素个数为_(R-P+N)%N_。

  1. 下列程序判断字符串s是否对称,对称则返回1+,否则返回0;如f("abba")返回1,f("abab")返回0。

int f(_char s[]_)

{

int i = 0, j = 0;

while (s[j])

{

_j++_;

}

for (j--; i < j && s[i] == s[j]; i++, j--)

{

;

}

return _i>=j_;

}

16、设二维数组A[-20..30,-30..20],每个元素占有4个存储单元,存储起始地址为200H(十六进制)。如按行优先顺序存储,则元素A[25,18]的存储地址为_269CH_;如按列优先顺序存储,则元素A[-18,-25]的存储地址为_604H_。

17、二维数组a[4][5][6](下标从0开始计,a有4*5*6个元素),每个元素的长度是2,则a[2][3][4]的地址是_10A4H_。(设a[0][0][0]的地址是1000H十六进制,数据以行为主方式存储)

18、n阶对称矩阵a满足a[i][j]=a[j][i],i,j=1..n,,用一维数组t[1..m]存储(按行向存储左下三角)时,t的长度为_n(n+1)/2_, 当i=j, a[i][j] = t[_j*(j+1)/2_], i>j, a[i][j] = t[_i*(i-1)/2+j_], i<j, a[i][j] = t[_j*(j-1)/2+i_]。

19、已知a数组元素共5个,依次为12,10,5,3,1;b数组元素共4个,依次为4,6,8,15,则执行如下所示的过程语句sort后得到c数组各元素依次为15,12,10,8,6,5,4,3,1;数组a,b,c的长度分别为l=5,m=4,n=9请在程序中方框内填入正确的成分,完成上述要求。

void sort(int a[], int b[], int c[])

{

int i, j, k, x;

int d[M];

for (i = 0; i < M; i++)

{

d[i] = _b[M-i-1]_;

}

i = 0;

j = 0;

k = 0;

while (i < L && j < M)

{

if (a[i] > d[j])

{

_x=a[i]_;

_i++_;

}

else

{

_x=d[j]_;

_j++_;

}

c[k] = x;

_k++_;

}

while (_i<L_)

{

c[k] = a[i];

k++;

i++;

}

while (_j<M_)

{

c[k] = d[j];

k++;

j++;

}

}

20、完善下列程序。下面的程序将数列1,2,3,…,n*n,依次按蛇型方式存放在二维数组A[1..n,1..n]中。如下图。

#include <stdio.h>

#define NMAX 10

int main(void)

{

int i, j, n, k, p, q, m;

int a[NMAX][NMAX]={0};

scanf("%d", &n);

m = 1;

for (k = 1; _k<2*n_; k++)

{

if (k < n)

{

q = k;

}

else

{

_q=2*n-k_;

}

for (p = 1; p <= q; p++)

{

if (_q%2==1_)

{

i = q-p+1;

j=p;

}

else

{

i = p;

j = q-p+1;

}

if (_k>=n_)

{

i = i+n-q;

j=j+n-q;

}

a[i][j] = m;

_m++_;

}

}

for (i = 1; i <= n; i++)

{

for (j = 1; j <= n; j++)

{

printf("%4d", a[i][j]);

}

printf("\n");

}

}

21、约瑟夫环问题:设有n个人围坐一圈,并按顺时针方向1—n编号。从第s个人开始进行报数,报数到第m个人,此人出圈,再从他的下一个人重新开始从1到m的报数进行下去 ,直到所有的人都出圈为止。

void Josef(int a[N+1], int s, int m)

{

int i, j, w, s1;

for (i = 1; i <= N; i++)

{

a[i] = i;

}

s1 = s;

for (i = N; i>= 2; i--)

{

s1 = _(s1+m-1)%i_; //计算出圈人数

if (s1== 0)

{

_s1=i_;

}

w = a[s1]; //a[s1]出圈

for (j = s1;_j<=i_; j++)

{

a[j] = a[j+1];

}

a[i]=w;

}

printf("出圈序列为:");

for (i = N; i>=1;i--)

{

printf("%d ", a[i]);

}

printf("\n");

}

22、算法Print及所引用的数组A的值如下,写出调用Print(1)的运行结果(其中n=15)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

A

B

C

D

E

F

G

O

O

H

0

I

J

K

L

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

A

B

C

D

E

F

G

O

O

H

0

I

J

K

L

(1)

2

0

0

0

3

0

4

0

0

0

(2)

i

1

1

2

3

4

j

1

4

3

2

1

v

2

4

3

3

4

(3)

24、已知广义表A=(9,7,(8,10,(99)),12),试用求表头和表尾的操作Head( )和Tail( )将原子元素99从A中取出来。

答:Head(Head(Tail(Tail(Head(Tail(Tail(A)))))))。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值