线性数据结构

数据结构 优点 缺点
数组 插入快 查找慢 ,删除慢 ,大小固定只能存储单一元素
有序数组 比无序数组查询快 插入慢 ,删除慢 ,大小固定只能存储单一元素
提供后进先出的存储方式 存储其他项慢
队列 提供先进先出的存储方式 存储其他项
链表 插入快 ,删除快 查找慢
二叉树 如果数是平衡的 ,则查找,插入,删除快 删除算法复杂
2-3-4树 查找,插入,删除快 ,树总是平衡的 算法复杂
哈希表 如果关键字已知则存储极快 删除慢 ,如果不知道关键字存储慢,对储存空间使用不充足
插入 ,删除快 ,对最大数据储存快 对其他数据存取慢
对现实世界建模 有些算法慢而复杂
红黑树 查找,插入,删除快 ,树总是平衡的 算法复杂

二叉堆

链表

树状数组

  • 指针

1. 指针变量(int *p) 与普通变量(int a)的关系

1
2
3
p ------ &a //&为取地址运算符
*p ------ a //*为间接运算符
*p=3 ------ a=3

2. 指针变量定义

1
int *p=NULL;

定义了一个指针p ,p指向一个内存空间 ,里面存放着一个内存地址。现在赋值为NULL(为0 ,表示特殊的空地址)。

3. 给指针变量p赋值

1
2
int a=3;
p=&a

即把a变量的内存地址给了p

*p的值为3 ,p为地址

4. 指针变量初始化

方法 说明
1 int *p=NULL; NULL为特殊的地址0 ,叫零指针
2 int *p=&a; p初始化为变量a的地址
3 int*p=new(int) 申请一个空间给p ,*p内容不确定

5. 指向结构体变量的指针

一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时,该指针变量的值是结构体变量的起始位置。

使用指针变量访问结构体成员示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <cstdio>
#include <iostream>
using namespace std;
struct student{
string name;
int age;
int fx;
};
student x={"xiaoming" ,13 ,100};
student *p;
int main()
{
p=&x;
cout << x.name << endl;
cout << (*p).age << endl;
cout << p->fx << endl;
}
输出

1
2
3
4
5
6
7
8
xiaoming
13
100

--------------------------------
Process exited after 0.05083 seconds with return value 0
请按任意键继续. . .

注:p->age 相当于 x.age。 ## 链表 ### 单链表 #### 1. 单链表结构体定义

1
2
3
4
5
struct name{
(类型)data
struct name *next;
//name为结构体名称 ,next指向下一个节点的指针
};
#### 2. 基本操作 - 初始化
1
2
3
4
5
/*
| 头指针L | NULL |
*/
L=new name;
L->next=NULL;

  • 创建

- 取值,查找

1
2
P=L->next;j=1;
P=P->next;j=2;

  • 插入

- 删除

相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<iostream>
#include<string>
using namespace std;

typedef struct LNode {
int data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode, *LinkList; //LinkList为指向结构体LNode的指针类型

void CreateList_R(LinkList &L)//尾插法创建单链表
{
//输入n个元素的值,建立带表头结点的单链表L
int n;
LinkList s, r;
L=new LNode;
L->next=NULL; //先建立一个带头结点的空链表
r=L; //尾指针r指向头结点
cout <<"请输入元素个数n:" <<endl;
cin>>n;
cout <<"尾插法(正序)创建单链表..." <<endl;
while(n--)
{
s=new LNode;//生成新结点
cin>>s->data; //输入元素值赋给新结点的数据域
s->next=NULL;
r->next=s;//将新结点s插入尾结点r之后
r=s;//r指向新的尾结点s
}
}

LinkList findmiddle(LinkList L)
{
LinkList p,q;
p=L; //p为快指针,初始时指向L
q=L; //q为慢指针,初始时指向L
while(p!=NULL&&p->next!=NULL)
{
p=p->next->next;//p为快指针一次走两步;
q=q->next; //q为慢指针一次走一步
}
return q;//返回中间结点指针
}

void Listprint_L(LinkList L) //单链表的输出
{
LinkList p;
p=L->next;
while (p)
{
cout<<p->data<<"\t";
p=p->next;
}
cout<<endl;
}

int main()
{
LinkList L,mid;
cout<<"创建单链表L:"<<endl;
CreateList_R(L);
cout<<"单链表数据为:"<<endl;
Listprint_L(L);
mid=findmiddle(L);
cout<<"单链表中间结点数据为:"<<mid->data<<endl;
return 0;
}

双向链表

  • 插入

1
2
3
4
P->pior->next=s;
S->pior=P->pior;
S->next=p;
P->next=S;

  • 删除