数据结构学习

#数据结构# 最近在修炼内功,因为程序 =  数据结构+算法

所以内功得拿起来了,稳固了

数据结构:是相互之间存在一种或多种特定关系的数据元素的集合

    按照视点不同,我们把数据结构分为逻辑结构和物理结构

       逻辑结构: 数据对象中数据元素之间得相互关系

          1.集合结构: 集合结构中得数据元素都同属于一个集合

    

         2.线性结构:各个数据元素之间是一对一得关系

3.树形结构:树形结构中的元素是存在一种一对多的层次关系

4.图像结构:        图形结构是多对多的关系

而物理结构:是指数据的逻辑结构在计算机中的存储形式

1.顺序存储结构:是把数据元素存在地址连续的存储单元里面,逻辑关系和物理关系一致的

2.链式存储结构:通过指针存储数据元素的地址,通过地址能找到相关数据元素的位置

抽象数据类型

 1.数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。

数据类型是按照值的不同进行划分的。在高级语言中,每个变量、常量和表达式都有
各自的取值范围。类型就用来说明变量或表达式的取值范围和所能进行的操作。

算法设计的要求

1.正确性

2.可读性

3.健壮性

4.时间效率高和存储量低

算法效率的度量方法

    1.事后统计方法 :这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对
不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。

     2.事前分析估算方法 :在计算机程序编制前,依据统计方法对算法进行估算。

函数的渐近增长:随着N的增长,判断一个算法的效率时,函
数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数

算法时间复杂度

        1.算法时间负责度定义:T(n)=O(f(n))

        2.推导大0阶方法 :

                2.1.用常数1取代运行时间中的所有加法常数。
                2.2.在修改后的运行次数函数中,只保留最高阶项。
                2.3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。

        3.常数阶:执行时间恒定的算法,我们称之为具有O(1)的时间复杂度

        4.线性阶段:它的循环的时间复杂度为O(n),因为循环体中的代码须要执行n次。

int i;
for(i = 0; i < n; i++){
  /*时间复杂度为0(1)*/
}

        5.对数阶:每次count乘以2之后,就距离n更近了一分。也就是说,有多少个2相乘后大于
n,则会退出循环。由2 x =n得到x=log 2 n。所以这个循环的时间复杂度为O(logn)。

int count = 1;
while(count < 0)
{
    count  =  count * 2
    /**时间复杂度为O(1)得程序步骤序列**/
}

        6.常数阶:内层本身是O(N)

int i , j;
for(i = 0; i < n; i++)
{
     for(j=0; j < n; j++)
     {
        /*时间复杂度为0(1)*/
     }
}

常见得时间复杂度

我这里只是写查询方式:比较常用的;

1.顺序表查询

算法的前提  我是JAVA 开发的,其他语言,你用通义灵码转换一下!!!!!

/* 顺序查找,a为数组,n为要查找的数组长度,key为要查找的关键字 */

    @Test
	int sequentialSearch(int[] a ,int n ,int key ) {

		for (int i = 0; i < n; i++) {
			if (a[i] == key){
					return i;
			}

		}
		return 0;


	}

/* 优化顺序查找,a为数组,n为要查找的数组长度,key为要查找的关键字 */

这个优化只是不需要每次去判断是否小于n。


	@Test
	int sequentialSearch2(int[] a ,int n ,int key ) {

		int i;
		/**
		 * 设置a[0]为关键值,我门成为“哨兵”
		 */
		a[0] = key;
		/**循环从数组尾部开始查找,直到找到关键值或查找结束*/
		i = n;
		while (a[i] != key){
			i -- ;
		}
		return i;

	}

2.二分查找法

/* 折半查找 */
	@Test
	int Binary_Search(int[] a ,int n ,int key ) {

		int low,hight,mid;
		//定义最低下标为记录首位
		low = 1;
		//定义最高下标为记录末位
		hight = n;
		while(low <= hight){
			/* 折半 */
			mid = (low + hight) /2;
			/* 若查找值比中值小 */
			if (key < a[mid]){
				/* 最高下标调整到中位下标小一位 */
				hight = mid - 1;
			}else if (key > a[mid]){
				/* 最低下标调整到中位下标大一位 */
				low = mid + 1;
			}else{
				/* 若相等则说明mid即为查找到的位置 */
				return mid;
			}
		}
		return 0;

	}

 2.2插值查找法(就是那个注释插值的)

mid=low+ (hight-low)*(key-a[low])/(a[hight]-a[low]);
/* 折半查找 */
	@Test
	int Binary_Search(int[] a ,int n ,int key ) {

		int low,hight,mid;
		//定义最低下标为记录首位
		low = 1;
		//定义最高下标为记录末位
		hight = n;
		while(low <= hight){
			/* 折半 */
			/*mid = (low + hight) /2;*/
			mid=low+ (hight-low)*(key-a[low])/(a[hight]-a[low]); /* 插值 */
			/* 若查找值比中值小 */
			if (key < a[mid]){
				/* 最高下标调整到中位下标小一位 */
				hight = mid - 1;
			}else if (key > a[mid]){
				/* 最低下标调整到中位下标大一位 */
				low = mid + 1;
			}else{
				/* 若相等则说明mid即为查找到的位置 */
				return mid;
			}
		}
		return 0;

	}

2.3斐波那契查找 JAVA 版

    /* 斐波那契查找 */
	private  static  int[] F;// 假设F是一个已填充好的斐波那契数列
	@Test
	int Fibonacci_Search(int[] a ,int n ,int key ) {

		int low,hight,mid,  k;
		//定义最低下标为记录首位
		low = 1;
		//定义最高下标为记录末位
		hight = n;
		k = 0;
		/* 计算n位于斐波那契数列的位置 */
		while (n > F[k] - 1){
			k++;
		}
		// 将不满的数值补全
		for (int j = n; j < F[k]; j++) {
			a[j] = a[n];
		}
		while (low <= hight){
			// 计算当前分隔的下标
			 mid = low + F[k - 1] - 1;;
			// 若查找记录小于当前分隔记录
			if(key < a[mid]){
				// 最高下标调整到分隔下标mid-1处
				hight = mid - 1;
				// 斐波那契数列下标减一位
				k -= 1;
			}
			// 若查找记录大于当前分隔记录
			else  if (key  > a[mid]){
				// 最低下标调整到分隔下标mid+1处
				low = mid + 1;
				// 斐波那契数列下标减两位
				k -= 2;
			}else {
				// 若相等则说明mid即为查找到的位置
				if(mid <= n){
					return mid;
				// 若mid>n说明是补全数值,返回n
				}else {
					return n;
				}
			}


		}
		// 没有找到对应值时返回0
		return 0;


	}

线性索引查找

        分三类:

                稠密索引 是指在线性索引中,将数据集中的每个记录对应一个索引项

--------------------------------------------------------------------------------------------------------------

                分块索引:数据集进行分块,使其分块有序,然后再对每一块建立一个索引
项,从而减少索引项的个数。
分块有序,是把数据集的记录分成了若干块,并且这些块需要满足两个条件(如下):

                          块内无序:即每一块内的记录不要求有序。当然,你如果能够让块内有序对查找
来说更理想,不过这就要付出大量时间和空间的代价,因此通常我们不要求块内
有序。

                           块间有序:例如,要求第二块所有记录的关键字均要大于第一块中所有记录的关
键字,第三块的所有记录的关键字均要大于第二块的所有记录关键字……因为只
有块间有序,才有可能在查找时带来效率。

------------------------------------------------------------------------------------------------------------------------

                倒排索引:在这里这张单词表就是索引表,索引项的通用结构是:


                        次关键码,例如上面的“英文单词”;
                        记录号表,例如上面的“文章编号”。
                        其中记录号表存储具有相同次关键字的所有记录的记录号(可以是指向记录的指针或者是该记录的主关键字

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值