一、数据结构的基本概念
1、基本结构
(1)集合
结构中的数据元素之间除了“同属于一个集合”之外没有其他关系
(2)线性结构
结构中的数据元素存在一对一的关系
(3)树形结构
结构中的数据元素存在一对多的关系
(4)图状结构或网状结构
结构中的数据元素存在多对多的关系
2、算法
(1)算法指的是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作
(2)算法的特性
a.有穷性
一个算法必须总是在执行有穷步之后结束,且每一步都可在有穷时间内完成
b.确定性
算法中的每一条指令都必须有确切的含义,确保不会产生二义性。并且在任何条件下,算法只有唯一的一条执行路径,即对于相同输入只能得出相同输出
c.可行性
可行即算法中茂数的曹志勇都是可以通过已经实现的基本运算执行有限次来实现的
d.输入
e.输出
(3)算法设计的要求
a.正确性
b.可读性
c.健壮性
d.效率与低存储量需求
(4)算法效率与空间需求的度量
a.时间复杂度
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记作:T( n ) = O( f( n ) ),即时间复杂度
b.空间复杂度
类似于时间复杂度,空间复杂度可记作:S( n ) = O( f( n ) )
二、线性表
1、定义
a.线性表是n个数据元素的有限序列
b.除了第一个和最后一个数据元素之外,每个数据元素都只有一个直接前驱和一个直接后继
2、线性表的顺序表示和实现
public class SqList {
private static int []list; //定义一维数组存储数据
private static int n; //定义线性表长度
//线性表初始化
public void SqlistInit(int n)
{
list = new int [n];
this.n = 0;
}
//设置线性表第i个元素
public void setSqlist(int i,int k)
{
try
{
if (i > 0 && i <= (n + 1))
{
list[i - 1] = k;
if (i == n + 1)
n++;
}
}
catch (Exception e)
{
System.out.println("您设置的第" + i + "个元素数组越界");
}
}
//在第i个位置插入元素
public void insertSqlist(int i, int k) {
if (n < list.length)
{
if (i <= 0)
i = 1;
if (i > n)
i = n + 1;
for (int j = n; j > i - 1; j--)
{
list[j] = list[j - 1];
}
list[i - 1] = k;
n++;
}
else
System.out.println("数组已满,无法插入" + k);
} //删除元素
public void deleSqlist(int i)
{
if (n != 0) { if (i <= 0 || i > n) {
System.out.println("输入不合法");
return;
} for (int j = i - 1; j < n; j++)
{
list[j] = list[j + 1];
}
n--; }
else
System.out.println("顺序表为空");
}}
2、线性表的链式表示和实现
(1)线性链表
public class Link {
//结点类
public class Node
{
//存放数据的变量
public int data;
//存放结点的变量
public Node next;
//构造方法,在构造时就能够给data赋值
public Node(int data)
{
this.data = data;
}
}
//定义头结点
Node head = null;
//插入结点
public void addNode(int d)
{
Node newN = new Node(d);
if(head == null)
{
head = newN;
}
Node temp = head;
while(temp.next != null)
{
temp = temp.next;
}
temp.next = newN;
}
//删除结点
public void insertNodeByIndex(int index)
{
//首先需要判断指定位置是否合法,
if(index<1||index>length()+1){
System.out.println("插入位置不合法。");
return;
}
int length = 1; //记录位置。
Node temp = head; //可移动的指针
while(head.next != null)
{//遍历单链表
if(index == length++)
{
//删除操作。
temp.next = temp.next.next;
return;
}
temp = temp.next;
}
}
//在链表中间插入结点
public void insertNode(int index,int d)
{
Node newN = new Node(d);
//判断指定位置是否合法,
if(index<1||index>length()+1)
{
System.out.println("插入位置不合法。");
return;
}
int length = 1; //记录位置。
Node temp = head; //可移动的指针
while(temp.next != null)//遍历单链表
{
if(index == length++)//判断是否到达指定位置。
{
//插入操作。
newN.next = temp.next;
temp.next = newN;
return;
}
temp = temp.next;
}
}
//查询链表长度
public int length()
{
int length = 0;
Node tmp = head;
while (tmp != null)
{
length++;
tmp = tmp.next;
}
return length;
}
}
(2)循环链表
同单链表,末尾结点node.next = head
(3)双向链表
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev; Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
其中prev为前驱结点