当我认真看完严蔚敏和吴伟民的数据结构(C语言版)的前两章时我才发现这本书讲的是太好了。理论与算法分析相结合是这本书真正的魅力所在。
第一章
- 数据的存储方式
1.集合 可以理解为一组相同类型的数据放在一起但彼此之间却没有任何联系
2.线性表 一组相同类型的数据放在一起,彼此之间只存在一种关系将它们联系起来,比如数组 array[4]={1,2,3,4};这些数据是由于array的下标联系在一起的。数组可以看做是一种简单的线性表。
3.树 存在一对多的这样的结构来组织数据的。后面我们学习的二叉树,三叉树。就是这样组织数据的模型。
4.图 多对多的结构来组织数据的。
数据结构在计算机内部就是数据的存储结构,也称为物理结构。
抽象数据类型可分为 1.原子类型(常见的单一变量)2.固定聚合类型(静态存储结构)3.可变聚合类型(动态存储类型)
- 算法
1.有穷性(即不能出现死循环)
2.确定性 (一条指令不能出现两种执行动作)
3.可行性(可以达到所要求的结果)
4.输入和输出 - 设计算法的要求
1.正确性(不正确何以达到要求的结果)
2.可读性(大型程序不是针对你自己看懂而言的)
3.健壮性(容错性)
4.效率和低存储性(速度快存储少)
第二章
- 线性表
1.术语介绍
a.数据元素(记录) 数据元素可以含多个数据项 比如对于人而言 人可以看做一个数据元素(记录) 那么他的身高,体重,学习成绩等等都可以看做是数据项
b.数据项
c.文件 由多个数据元素(记录)构成的线性表。
结构体表示文件如下 结构体可以看出来你是如何组织数据的
typedef struct data//表示每个人的信息
{
char name[10];
char sex[10];
char galss[10];
}Data,*DATA;//数据元素
typedef struct
{
DATA array[10];//表示是个人
}File;
例题分析
已知线性表LA和LB中的数据元素按照非递减有序排序,现要求将LA和LB归并为一个新的线性表的LC,且LC中人数据元素按照非递减的有序排列。
LA[4]={3,5,8,11}
LB[7]={2,6,8,9,11,15,20}
这样的题完全可以按照下标的运动一次进行比较
如果LA[i]>=LB[j] 那么将LB[j]的元素放到LC中,然后++j;相反则++i。这就是线性表组织数据的简单所在,根据下标可以做好多事。
- 线性表的顺序表示和实现
线性表的顺序表示正是运用了线性表数据不仅逻辑上存储相邻而且物理存储上也相邻(实际是相差一个数据元素的占位数)。
arr[4]={1,2,3,4};我们要获得arr[3]的值我们不仅可以通过arr[3]直接获得,换可以通过arr+3获得。这种获得数据的方式对于其他存储类型来说是不可能实现的。
*** 还是分析上述的题,如果要将LA的数据插到LB中且不允许申请新的空间的话插入的话是不是特别麻烦,每比较一次找到插入的位置,先要将LB中找到的插入位置的后面所有元素都后移一位。当数据特别大的时候是不是所耗费的事间就特别多,所以接下来就是线性链表(单链表)的用处了。
- 线性链表
结构体是灵魂所以先写出线性链表的结构体
typedef struct Node
{
ElementType data;//数据域
struct Node*next;//指针域 存放下一节点的位置
}Node,*NODE;
线性链表在对数据的插入、删除操作时特别方便所以它无意是线性表最好的组织数据的算法
下面就本章的一个题进行写代码“”一元多项式的加法“”
#include<stdio.h>
#include <stdlib.h>
typedef struct node
{
int coef;//系数
int exp;//指数
struct node*next;
}NODE,*PNODE;
void initNode(PNODE *head);//初始化链表
void insertData(PNODE head,int coef,int exp);//插入链表
void PolyAdd(PNODE head1, PNODE head2);//多项式相加
void showNode(PNODE head);//展示结点
void freeNode(PNODE head);//释放结点
int main()
{
PNODE head1, head2;
initNode(&head1);
initNode(&head2);
int coef, exp;
printf("请输入head1的链表的系数与指数\n");
for (int i = 0; i < 5; i++)
{
scanf("%d %d", &coef, &exp);
insertData(head1, coef, exp);
}
showNode(head1);
printf("\n请输入head2的链表的系数和指数\n");
for (int i = 0; i < 4; i++)
{
scanf("%d %d", &coef, &exp);
insertData(head2, coef, exp);
}
showNode(head2);
printf("\n则新形成的链表为:\n");
PolyAdd(head1, head2);
return 0;
}
void initNode(PNODE *head)
{
(*head) = (PNODE)malloc(sizeof(NODE));
(*head)->next = NULL;
}
void insertData(PNODE head, int coef, int exp)
{
PNODE temp = (PNODE)malloc(sizeof(NODE));
temp->coef = coef;
temp->exp = exp;
/*尾插法*/
PNODE p = head;
while (p ->next!= NULL)
{
p = p->next;
}
p->next = temp;
temp->next = NULL;
}
void PolyAdd(PNODE head1, PNODE head2)//该式的相加是将加入的数据放在tail的指针上面的
{
NODE *p, *q, *tail, *temp;//temp是临时处理数据的结点
int sum;//和多项式中的系数
p = head1->next;
q = head2->next;
tail = head1;//和多项式的尾结点,也可以理解为头结点
while (p != NULL&&q != NULL)
{
if (p->exp < q->exp)//p指向的多项式指数小于q的指数,将p结点加入到和结点的后面
{
tail->next = p;
tail = p;
p = p->next;
}
else
if (p->exp==q->exp)
{
sum = p->coef + q->coef;//系数的相加
if (sum != 0)
{
p->coef = sum;
tail->next = p;
tail = p;
p = p->next;
temp = q; q = q->next; free(temp);//释放head2的结点
}
else//如果sum==0的话释放两个节点
{
temp = p; p = p->next; free(temp);
temp = q; q = q->next; free(temp);
}
}
else//q->exp>p->exp的话将q加到和多项式中
{
tail->next = q;
tail = q;
q = q->next;
}
}
if (p != NULL)//没有存完的加到和多项式之后
{
tail->next = p;
}
else
{
tail->next = q;
}
printf("\n");
showNode(head1);
}
void showNode(PNODE head)
{
PNODE p;
p = head->next;
while (p != NULL)
{
printf("%d,%d\t", p->coef, p->exp);
p = p->next;
}
}
void freeNode(PNODE head)
{
PNODE p,temp;
p = head->next;
while (p != NULL)
{
temp = p;
p = p->next;
free(temp);
}
}