数据结构之算法设计题专攻


据可靠情报,算法设计题主要集中:

2 , 3 , 7 , 8 章节



分别是

  • 第2章 线性表

  • 第3章 栈和队列

  • 第7章 查找

  • 第8章 排序


主要

前插法后插法创建单链表,合并有个有序链表

线性表课后习题算法设计题1,7

链栈的入栈和出栈

链队

折半查找

冒泡排序

快速排序

堆排序


前插法后插法创建单链表,合并有个有序链表

代码描述:

void CreateList_H(LinkList& L, int n)
{
	L = new Lnode;
	L->next = NULL;
	for (int i = 0; i < n; ++i) {
		p = new Lnode;
		cin >> p->data;
		p->next = L->next;
		L->next = p;
	}
}


算法时间复杂度为 O(n)。

void CreateList_R(LinkList& L, int n) {
	L = new Lnode;
	L->next = NULL;
	r = L;
	for (i = 0; i < n; ++i) {
		p = new Lnode;
		cin >> p->data;
		p->next = null;
		r->next = p;
		r = p;
	}
}

算法时间复杂度为 O(n)。


void MergeList(LinkList& La, LinkList& Lb, LinkList& Lc)
{
    
    
	pa = La->next;  pb = Lb->next;
	
	Lc = pc = La;  //用La的头结点作为Lc的头结点
	while (pa && pb)
	{
    
    
		if (pa->data < pb->data) {
    
     pc->next = pa; pc = pa; pa = pa->next; }
		//取较小者La中的元素,将pa链接在pc的后面,pa指针后移
		else if (pa->data > pb->data) {
    
     pc->next = pb; pc = pb; pb = pb->next; }
		//取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移
		else //相等时取La中的元素,删除Lb中的元素
		{
    
    
			pc->next = pa; pc = pa; pa = pa->next;
			q = pb->next; delete pb; pb = q;
		}
	}
	pc->next = pa ? pa : pb;    //插入剩余段
	delete Lb;            //释放Lb的头结点
}

线性表课后习题算法设计题1,7

二.P53 算法设计题(1) (7)

(1 )将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的存储空间。表中不允许有重复的数据。

和上面一样!!!


(7)设计一个算法,将链表中所有结点的链接方向 “原地” 逆转,即要求仅利用原表的存储空间,换句话说,要求算法的空间复杂度为 0(1)。

//利用的是前插法
void Do(LinkList& L) {
    
    

	//1->2->3->4
	r = L->next;
	L->next = NULL;
	while (r) {
    
    
		p = r->next;
		r->next = L->next;
		L->next = r;
		r = p;
	}
}

链栈的入栈和出栈

void Push(LinkStack& L, SElemType e) {
    
    
	p = new StackNode;
	p->data = e;
	p->next = L;
	L = p;
}
void pop(LinkStack& L, SElemType e) {
    
    
	if (L == NULL)e = NULL;
	else
	{
    
    
		p = L;
		e = L->data;
		L = L->next;
		delete p;
	}
}

折半查找

int search_bin(SStable ST,keyType key){
    
    
low =1;
hight = ST.length;
while(low<=high
{
    
    
	mid = (low + high)/2;
	if(key == ST.R[mid].key)
		return mid;
	else if (key<ST.R[mid].key)
		high = mid-1
	else low = mid +1

}
return 0;


冒泡排序

void BubbleSort(Sqlist &L)
{
    
    
	m = L.length - 1 ;
	flag = 1;
	while ((m>0)&&(flag==1))
	{
    
    
		flage = 0;
		for (j=1;j<=m;j++){
    
    
			if(L.r[j].key>L.r[j+1].key)
			{
    
    
				flag = 1;
				t = L.r[j];
				L.r[j]=L.r[j+1];
				L.r[j+1] = t;
			}
			--m;
		}
	
	}
}



假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意:不设头指针),试编写相应的置空队列,判断队列是否为空,入队和出队等算法

在这里插入图片描述在这里插入图片描述
在这里插入图片描述


在数学上有一个著名的“阿克曼(Ackermann)函数”,该函数定义如下:

在这里插入图片描述
(1)写出Ack(m,n)的递归算法

int Ack(int m, int n)
//Ack函数的递归算法
{
    
    
If(m==0)
   return n+1;
else if (m!=0 && n==0)
   return Ack(m-1, 1);
Else
   return Ack(m-1,Ack(m,m-1));
}

(2)写出计算Ack(m,n)的非递归算法

int Ack(int m, int n)
//Ack函数的递归算法
{
    
    
    for(j=0;j<n;j++) 
    akm[0][j] = j+1;//得到Ack(0,n)的值
    for(i=0;i<m;i++)
    {
    
    
        akm[i][0] = akm[i-1][1];
        for(j=1;j<n;j++)
        akm[i][j] = akm[i-1][akm[i][j-1]];
    }
    return akm[m][n];
}

猜你喜欢

转载自blog.csdn.net/Touale/article/details/112971662