数据结构与算法二

1.课程安排表:

1. 线性表

2. 字符串

3. 栈和队列

4.树

5.查找

6.排序

7.暴力枚举法

8.广度优先搜索

9.深度优先搜索

10.分治

11.贪心

12.动态规划

13.图

14.数学方法与常见模型

15.大整数运算

16. 基础功能

2.   编程技巧:

1.把较大的数组放在main 函数(全局变量)外,作为全局变量,这样可以防止栈溢出,因为栈的大小是有限制的。GCC (C编译器) 段错误

2.如果能够预估栈,队列的上限,则不要用stack,queue,使用数组来模拟,这样速度最快。

3.输入数据一般放在全局变量,且在运行过程中不要修改这些变量。

4.在判断两个浮点数a 和b 是否相等时,不要用a==b,应该判断二者之差的绝对值fabs(a-b) 是否小于某个阈值,例如1e-9。

5.判断一个整数是否是为奇数,用x % 2 !=0,不要用x % 2 ==1,因为x 可能是负数。

6.用char 的值作为数组下标(例如,统计字符串中每个字符出现的次数),要考虑到char 可能是负数。有的人考虑到了,先强制转型为unsignedint 再用作下标,这仍然是错的。正确的做法是,先强制转型为unsignedchar,再用作下标。这涉及C++ 整型

提升的规则,就不详述了。

3.线性表小结:

题目:快速找到未知长度单链表的中间节点。

设置2个指针,一开始同时指向头,第一个指针比第二个指针快2倍

4. 字符串函数的内部实现

1.strlen

描述:实现strlen,获取字符串的长度。函数原型如下:

int strlen(const char *str)

代码:

int strlen(const char *str)
{
	const char *s;
	for(s=str; *s; ++s)
		;
	return (s-str);
}

2.strcpy

实现strcpy,字符串拷贝函数,函数原型如下:

char*strcpy(char *to, const char *from);

代码:

char *strcpy(char *to, const char *from)
{
	assert(to != NULL  && from != NULL);//断言错误
	char *p = to;
	while((*p++ = *from++) != '\0')
	;
	return to;
}

5.在排列中实现下一次排列

例如:数字1,2,3

1 2 3       ;    当前序号1

1 3 2       ;    当前序号2

2 1 3       ;    当前序号3

2 3 1       ;    当前序号4

3 1 2       ;    当前序号5

3 2 1       ;    当前序号6

三个数字1,2,3,有6种可能的排序情况,上述分别将序号都列举了出来。

那么现在需要解决的问题就是:已知当前排列中的序号 N, 求下一个序列 N+1。

求解过程:

为了便于操作,我们假设5个数字,分别是1,2,3,4,5

测试序列:以当前序列:1,4,3,5,2求出它的下一次排列。

现在将问题分解为4步骤:

1. 从后向前找出第一个不符合降序排列的数的下标,记为 i_pos,在本例子中那么就是数字3,下标i_pos 就是2。这里解释下何为第一个“不符合降序排列的数”,以例子来解释,从后向前找数的过程中,5,2,  是一个降序的排列,而3,5,2, 则破坏了这个降序的排列结构。

2. 在第一步找到的降序队列中,从其中找出大于下标为i_pos 的数,并且这个数在所有大于下标为i_pos 的数列中是最小的。那么以例子来说,这一步找到的数就是5,记录下标为j_pos;

3. 交换i_pos, 和 j_pos 下标的值。  执行完之后: 1,4,5,3,2

4. 从下标i_pos+1 开始知道末尾,对数列进行升序。例子中就应该是对 3,2 进行升序,最后的结果就是: 1,4,5,2,3

5. 最后输出结果。

代码实现:

#include <iostream>
#define swapData(x,y) {int tmp=x; x = y; y = tmp;}

using namespace std;

int next_permutation(int *num, int n)
{
	int length = n-1;
	int i_pos=-1;

	for(int i=length; i > 0; i --)
	{
		if(num[i]>num[i-1])
		{
			i_pos = i-1;
			break;
		}
	}
	// 判断是否到了末尾,即全部序列是降序的
	if(i_pos==-1) return 0;

	int j_pos;
	for(int i=length; i > i_pos; i--)
	{
		if(num[i] > num[i_pos])
		{
			j_pos = i;
			break;
		}
	}

	swapData(num[i_pos], num[j_pos]);

	//冒泡排序
	for(int i=i_pos+1; i < n; i++)
	{
		for(int j=length;  j > i; j--)
		{
			if(num[j] < num[j-1])
				swapData(num[j], num[j-1]);
		}
	}

	return 1;
}

main()
{
	int num[5]={1,2,3,4,5};
	do
	{
		for(int i=0; i <= 4; i++)
			cout << num[i] << " ";
		cout << endl;
	}while(next_permutation(num, 5));
	return 0;
}

数据结构与算法二,布布扣,bubuko.com

时间: 2024-09-29 08:13:53

数据结构与算法二的相关文章

Java数据结构和算法(二)——数组

数组的用处是什么呢?--当你需要将30个数进行大小排列的时候,用数组这样的数据结构存储是个很好的选择,当你是一个班的班主任的时候,每次要记录那些学生的缺勤次数的时候,数组也是很有用.数组可以进行插入,删除,查找等. 1)创建和内存分配 Java中有两种数据类型,基本类型和对象类型,也有人称为引用类型,Java中把数组当成对象,创建数组时使用new操作符. int array[] = new int[10]; 既然是对象,那么array便是数组的一个引用,根据Java编程思想(一) -- 一切都是

[数据结构与算法]二叉排序(搜索)树实现

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4289804.html 定义 二叉排序树又称二叉查找树或二叉搜索树,它或者是一棵空树,或者是具有如下性质的二叉树:1.若它是左子树非空,则左子树上所有节点的值均小于根节点的值2.若它的右子树非空,则右子树上所有节点的值均大于根节点的值3.左.

数据结构和算法二(数组)

一.数组 1.概念 数组是一种线性表数据结构,它用一种连续的内存空间,来存储一组具有相同类型的数据. 线性表:数组.链表.队列.栈等 非线性表:二叉树.堆.图等 2.连续的内存空间和相同类型的数据 优点:具有随机范文的特性,根据下标随机访问的时间复杂度为O(1) 缺点:低效的插入和删除 插入:最好O(1),最坏O(n),平均O(n) 插入:数组若无序,插入新的元素时,可以将第K个位置元素移动到数组末尾,把新的元素插入到第K个位置,此时复杂度为O(1) 删除:最好(1),最坏O(n),平均O(n)

python进阶(数据结构和算法[二])

找到最大或者最小的N个元素 heapq模块有两个函数–nlargest()和nsmallest()正好能解决我们的问题. >>> print(heapq.nlargest(3, nums)) [43, 23, 8] >>> print(heapq.nsmallest(3,nums)) [-1, 1, 2] #another import heapq portfolio = [ {'name': 'IBM', 'shares': 100, 'price': 91.1},

【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现

  本篇是数据结构与算法的第三篇,本篇我们将来了解一下知识点: 队列的抽象数据类型 顺序队列的设计与实现 链式队列的设计与实现 队列应用的简单举例 优先队列的设置与实现双链表实现 队列的抽象数据类型   队列同样是一种特殊的线性表,其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out).我们把向队列中插入元素的过程称为入队(Enqueue),删除元素的过程称为出队(Dequeue)并把允许入队的一端称为队尾,允许出的的一端称为队头,没有任何元素的队列

数据结构与算法系列研究二——栈和队列

栈和队列的相关问题分析 一.栈和队列定义 栈和队列是两种重要的数据结构.从结构特性角度看,栈和队列也是线性表,其特殊性在于它们的基本操作是线性表的子集,是操作受限的线性表,可称为限定性的数据结构:从数据类型角度看,其操作规则与线性表大不相同,是完全不同于线性表的抽象数据类型.                    图1 栈的结构                                                 图2 队列的结构   1.1.栈是限定在表的一端进行插入和删除操作的线性

php面试题之二——数据结构和算法(高级部分)

二.数据结构和算法 1.使对象可以像数组一样进行foreach循环,要求属性必须是私有.(Iterator模式的PHP5实现,写一类实现Iterator接口)(腾讯) <?php class Test implements Iterator{ private $item = array('id'=>1,'name'=>'php'); public function rewind(){ reset($this->item); } public function current(){

数据结构(十二)——排序算法

数据结构(十二)--排序算法 一.排序简介 1.排序的一般定义 排序是计算机中经常进行的操作,目的在于将一组无序的数据元素调整为有序的数据元素.序列:1,20,45,5,2,12排序后:1,2,5,12,20,45 2.排序的数学定义 3.排序的稳定性 如果序列中的两个元素R[i].R[j],关键字分别为K[i].K[j],并且在排序之前R[i]排在R[j]前面,如果排序操作后,元素R[i]仍然排在R[j]前面,则排序方法是稳定的:否则排序是不稳定的. 4.排序实现的关键 比较:任意两个数据元素

Java数据结构和算法(二)树的基本操作

Java数据结构和算法(二)树的基本操作 一.树的遍历 二叉树遍历分为:前序遍历.中序遍历.后序遍历.即父结点的访问顺序 1.1 前序遍历 基本思想:先访问根结点,再先序遍历左子树,最后再先序遍历右子树即根-左-右.图中前序遍历结果是:1,2,4,5,7,8,3,6. // 递归实现前序遍历 public void preOrder() { System.out.printf("%s ", value); if (left != null) { left.preOrder1(); }