今天正式开始学习数据结构。
计划上课期间每周学习一章,十周内学完数据结构。
本周内容:数据结构概论,主要是数据结构的概念性问题
1. 什么是数据结构?
数据结构研究如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构储存到主存储器(内存)中。
也就是将数组、链表、树、图等特定的数据类型的每个独立元素个体,和个体之间的关系储存到内存中。
数据结构 = 个体 +个体之间的关系, 需要存储每个独立的个体,和个体之间的关系。
2. 衡量算法的标准
1>. 时间复杂度——程序大概要执行核心步骤的次数,而非执行的时间,因为机器的性能不同。
2.> 空间复杂度——算法执行过程中大概所占用的最大的内存
3>. 难易程度——程序实现最关注的地方
4>. 健壮性——抗干扰性能强。
3. 数据元素之间的关系在计算机中有两种不同的表示方法:
1> 顺序映像法
对应顺序存储结构。特点是借助元素在存储器中的相对位置来表示数据元素只加的逻辑关系。
2> 非顺序映像法
对应链式存储结构。特点是借助指示元素存储地址的指针表示数据元素之间的逻辑关系。
4. 三元组数据结构
1> 使用范围
三元组数据结构主要用来存储稀疏矩阵。
用来存放非常大的数组,而且数组中的元素大部分是重复元素(这里我们把这些重复的元素值认为是默认值),只有少数是不同的元素(需要单独保存的特殊值)。
2> 程序实现
文件c1.h
<span style="font-family:Courier New;font-size:12px;">/**********************************************
Function: 定义结果状态值(OK...)
<span style="white-space:pre"> </span> 包含常用头文件
Description: 包含的头文件很多,实际使用的时候
自行修改
**********************************************/
#pragma once
#ifndef __C1_H__
#define __C1_H__
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream> // cout cin
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
// #define OVERFLOW -2因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean;// Boolean是布尔类型,其值是TRUE或FALSE
#endif</span>
// c1-1.h采用动态分配的顺序存储结构
// 定义数据结构和ElemType的数据类型
#pragma once // 防止重复包含
#ifndef __C1_1_H__
#define __C1_1_H__
//以下2行可根据需要选用一个(且只能选用一个),而不需改变基本操作bo1-1.cpp
typedef int ElemType; //定义抽象数据类型ElemType在本程序中为整型
//typedef double ElemType; //定义抽象数据类型ElemType在本程序中为双精度型
typedef ElemType *Triplet; //由InitTriplet分配3个元素存储空间
// Triplet类型是ElemType类型的指针,存放ElemType类型的地址
#endif
#pragma once
#ifndef __BO1_1__
#define __BO1_1__
#include "c1.h"
#include "c1-1.h"
// bo1-1.cpp抽象数据类型Triplet和ElemType(由c1-1.h定义)的基本操作(8个)
//操作结果:构造三元组T,依次置T的3个元素的初值为v1,v2和v3(见图1 2)
Status InitTriplet(Triplet &T, ElemType v1,ElemType v2,ElemType v3);
//操作结果:三元组T被销毁(见图1 3)
Status DestroyTriplet(Triplet &T);
//初始条件:三元组T已存在,1≤i≤3。操作结果:用e返回T的第i元的值
Status Get(Triplet T,int i,ElemType &e);
//初始条件:三元组T已存在,1≤i≤3。操作结果:改变T的第i元的值为e
Status Put(Triplet T,int i,ElemType e);
//初始条件:三元组T已存在。操作结果:如果T的3个元素按升序排列,则返回1;否则返回0
Status IsAscending(Triplet T);
//初始条件:三元组T已存在。操作结果:如果T的3个元素按降序排列,则返回1;否则返回0
Status IsDescending(Triplet T);
//初始条件:三元组T已存在。操作结果:用e返回指向T的最大元素的值
Status Max(Triplet T,ElemType &e);
//初始条件:三元组T已存在。操作结果:用e返回指向T的最小元素的值
Status Min(Triplet T,ElemType &e);
#endif
// bo1-1.cpp抽象数据类型Triplet和ElemType(由c1-1.h定义)的基本操作(8个)
#include "c1.h"
#include "c1-1.h"
Status InitTriplet(Triplet &T, ElemType v1,ElemType v2,ElemType v3)
{ //操作结果:构造三元组T,依次置T的3个元素的初值为v1,v2和v3(见图1 2)
if(!(T=(ElemType *)malloc(3*sizeof(ElemType))))
exit(OVERFLOW);
T[0]=v1,T[1]=v2,T[2]=v3;
return OK;
}
Status DestroyTriplet(Triplet &T)
{ //操作结果:三元组T被销毁(见图1 3)
free(T);
T=NULL;
return OK;
}
Status Get(Triplet T,int i,ElemType &e)
{ //初始条件:三元组T已存在,1≤i≤3。操作结果:用e返回T的第i元的值
if(i<1||i>3)
return ERROR;
e=T[i-1];
return OK;
}
Status Put(Triplet T,int i,ElemType e)
{ //初始条件:三元组T已存在,1≤i≤3。操作结果:改变T的第i元的值为e
if(i<1||i>3)
return ERROR;
T[i-1]=e;
return OK;
}
Status IsAscending(Triplet T)
{ //初始条件:三元组T已存在。操作结果:如果T的3个元素按升序排列,则返回1;否则返回0
return(T[0]<=T[1]&&T[1]<=T[2]);
}
Status IsDescending(Triplet T)
{ //初始条件:三元组T已存在。操作结果:如果T的3个元素按降序排列,则返回1;否则返回0
return(T[0]>=T[1]&&T[1]>=T[2]);
}
Status Max(Triplet T,ElemType &e)
{ //初始条件:三元组T已存在。操作结果:用e返回指向T的最大元素的值
e=T[0]>=T[1]?T[0]>=T[2]?T[0]:T[2]:T[1]>=T[2]?T[1]:T[2];
return OK;
}
Status Min(Triplet T,ElemType &e)
{ //初始条件:三元组T已存在。操作结果:用e返回指向T的最小元素的值
e=T[0]<=T[1]?T[0]<=T[2]?T[0]:T[2]:T[1]<=T[2]?T[1]:T[2];
return OK;
}
/****************************************************************************
Function: 检验三元组数据结构的8种基本操作(在bo1-1.cpp中实现)
File Name:main1-1.cpp
From:高一凡
Author:Greyson
Date:2014.10.10
****************************************************************************/
#include <iostream>
#include"c1.h" // 要将程序中所有#include命令所包含的文件拷贝到当前目录下
#include"c1-1.h" // 在此命令之前要定义ElemType的类型
#include"bo1-1.h" // 在此命令之前要包括c1-1.h文件(因为其中定义了Triplet)
int main()
{
Triplet T;
ElemType m;
Status i;
// 初始化三元组T,其3个元素依次为5,7,9
i = InitTriplet(T,5,7,9);
// i=InitTriplet(T,5.0,7.1,9.3); // 当ElemType为双精度型时,可取代上句
printf("调用初始化函数后,i=%d(1:成功) T的3个值为", i);
std::cout<<T[0]<<' ' <<T[1]<<' ' <<T[2]<<std::endl; // 为避免ElemType的类型变化的影响,用cout取代printf()。注意结尾要加endl
// 将三元组T的第2个值赋给m
i = Get(T,2,m);
if( i == OK ) // 调用Get()成功
std::cout<<"T的第2个值为"<<m<<std::endl;
// 将三元组T的第2个值改为6
i = Put(T,2,6);
if( i == OK ) // 调用Put()成功
std::cout<<"将T的第2个值改为6后,T的3个值为"<<T[0]<<' ' <<T[1]<<' ' <<T[2]<<std::endl;
// 此类函数实参与ElemType的类型无关,当ElemType的类型变化时,实参不需改变
i=IsAscending(T);
printf("调用测试升序的函数后,i=%d(0:否1:是)\n",i);
i=IsDescending(T);
printf("调用测试降序的函数后,i=%d(0:否1:是)\n",i);
// 测试Max()函数
if( (i = Max(T,m)) == OK ) // 先赋值再比较
std::cout<<"T中的最大值为"<<m<<std::endl;
// 测试min()函数
if( (i = Min(T,m)) == OK )
std::cout<<"T中的最小值为"<<m<<std::endl;
// 销毁三元组结构。函数也可以不带回返回值
DestroyTriplet(T);
std::cout<<"销毁T后,T="<<T<<"(NULL)"<<std::endl;
return 1;
}