数据结构-c语言读书报告,数据结构读书笔记(一)(C语言)

第一章   关于数据结构

1.数据结构研究什么?(计算机加工的对象由数值——>非数值)

将现实生活中大量而复杂的问题(非数值问题)以特定的数据类型(逻辑结构)和特定的存储结构(物理结构)保存到主存储器中,以及在此基础上为实现某个功能(删除、排序)相对应的操作。

重点理解:1. 包含的数据元素

2.元素之间的关系

3.这些数据元素在计算机上如何存储

4.建立在这种数据结构上的操作

2.数据的逻辑结构:

0818b9ca8b590ca3270a3433284dd417.png

3.存储结构(物理结构):

1)顺序存储结构(借助元素在存储器中的相对位置)

2)链式存储结构(借助指针)

4.抽象数据类型ADT:

ADT抽象数据类型名

{

数据对象:

数据关系:

基本操作:

}

5、时间复杂度:

取决定性作用语句的重复次数

第二章    线性表

1.线性结构的基本特征:

1)集合中必存在唯一的一个“第一个元素”;

2)集合中必存在唯一的一个“最后元素”;

3)除最后元素外,均有唯一的后继;

4)除第一元素之外,均有唯一的前驱;

2.ADT

ADT List

{

数据对象:D={ a1,a2, a3, ... an};

数据关系:R={, , … };

基本操作:

InitList(&L); //操作结果:构造线性表;

DestroyList(&L); //操作结果:销毁线性表;

ListEmpty(L); //操作结果:若L为空表,则返回TRUE,否则FALSE;

ListLength(L); //操作结果:返回L中元素个数;

PriorElem(L,cur_e,&pre_e)//操作结果:cur_e是L的元素,但不是第一个

//则用pre_e返回它的前驱。若操作失败,pre_e无定义

NextElem(L,cur_e,&next_e)//操作结果:cur_e是L的元素,但不是最后一个,

//则用next_e返回它的后继。若操作失败,next_e无定义

GetElem(L,i,&e) // 1<= i <=LengthList(L) 操作结果:用e返回L中第i个元素的值。

LocateElem(L,e,compare())//compare()是元素判定函数。返回L中第一个与e满足compare()的元素位序。

//若这样的元素不存在,则返回值为0。

ListTraverse(L,visit( )) //依次对L的每个元素调用函数visit( ).一旦visit( )失败,则操作失败

ClearList(&L) //操作结果将L重置为空表。

PutElem(L,i,&e) //1<=i<=LengthList(L) 结果:L中第i个元素赋值为e

ListInsert(&L,i,e) //1<=i <=LengthList(L) +1 结果:在L的第i个元素之前插入新的元素e,L的长度增1

ListDelete(&L,i,&e)//1<=i <=LengthList(L) 结果:删除L的第i个元素,并用e返回其值,,L的长度减1

}ADT List

3.顺序实现

1)存储结构:

0818b9ca8b590ca3270a3433284dd417.png

#define LIST_INIT_SIZE 10

#define INCREAMENT

struct SqList

{

ElemType * elem;

int length;

int listsize;

};

2)基本操作

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

//L的位置固定在第一个元素的位置,要操作的话要另外设一个变量

void InitList(SqList & L )

{

L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType) );

L.length = 0;

L.listsize = LIST_INIT_SIZE;

}

void DestroyList(SqList & L)

{

free(L.elem);

L.elem = NULL;

L.length = 0;

L.listsize = 0;

}

void ClearList( SqList & L)

{

L.length = 0;

}

Status ListEmpty( SqList L)

{

if( L.length != 0 )

return FALSE;

else

return TRUE;

}

int ListLength(SqList L)

{

return L.length;

}

Status GetElem(SqList L, int i , ElemType & e)

{

if( i < 1 || i > L.length )

return ERROR;

e = *(L.elem + i - 1);

return OK;

}

int LocateElem(SqList L,ElemType e, Status(*compare)(ElemType , ElemType))

{

ElemType * p;

p = L.elem;

int i = 1;

while(i < L.length && !(compare(e, *p)))

{

i++;

p++;

}

if( i< L.length)

return i;

else

return 0;

}

Status PriorElem(SqList L, ElemType cur_e, ElemType & pre_e)

{

ElemType * p;

p = L.elem + 1; //p 和 i 之间进行合作

int i = 2;

while(i < L.length && *p!=cur_e)

{

i++;

p++;

}

if( i< L.length)

{

pre_e = *(--p);

return OK;

}

else

return INFEASIBLE;

}

Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)

{ // 初始条件:顺序线性表L已存在

// 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,

// 否则操作失败,next_e无定义

int i=1;

ElemType *p=L.elem;

while(i

{

i++;

p++;

}

if(i==L.length)

return INFEASIBLE; // 操作失败

else

{

next_e=*++p;

return OK;

}

}

Status ListInsert(SqList & L, int i , ElemType e)

{

if(i < 1 || i > L.length + 1)

return ERROR;

ElemType * newbase;

if(L.length >= L.listsize)

{

newbase = (ElemType *)realloc(L.elem,( L.listsize + INCREAMENT) * sizeof(ElemType));

L.listsize = L.listsize + INCREAMENT;

if(!newbase)

exit(OVERFLOW);

L.elem = newbase;

}

ElemType * p,*q;

p = L.elem + L.length -1;

q = L.elem + i -1;

for(p = L.elem + L.length -1; p >= q; --p)

{

*(p + 1) = * p;

}

*q = e;

L.length = L.length + 1;

return OK;

}

Status ListDelete(SqList &L,int i,ElemType &e) // 算法2.5

{ // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)

// 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1

ElemType *p,*q;

if(i<1||i>L.length) // i值不合法

return ERROR;

p=L.elem+i-1; // p为被删除元素的位置

e=*p; // 被删除元素的值赋给e

q=L.elem+L.length-1; // 表尾元素的位置

for(++p;p<=q;++p) // 被删除元素之后的元素左移

*(p-1)=*p;

L.length--; // 表长减1

return OK;

}

void ListTraverse(SqList L,void(*vi)(ElemType & ))

{ // 初始条件:顺序线性表L已存在

// 操作结果:依次对L的每个数据元素调用函数vi()

// vi()的形参加'&',表明可通过调用vi()改变元素的值

ElemType *p;

int i;

p=L.elem;

for(i=1;i<=L.length;i++)

vi(*p++);

printf("\n");

}

typedef struct LNode

{

ElemType data;

struct LNode *next;

};

typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */

0818b9ca8b590ca3270a3433284dd417.png                 

0818b9ca8b590ca3270a3433284dd417.png

// bo2-2.cpp 带有头结点的单链表(存储结构由c2-2.h定义)的基本操作(12个),包括算法2.8,2.9,2.10

void InitList(LinkList &L)

{ // 操作结果:构造一个空的线性表L

L=(LinkList)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点

if(!L) // 存储分配失败

exit(OVERFLOW);

L->next=NULL; // 指针域为空

}

void DestroyList(LinkList &L)

{ // 初始条件:线性表L已存在。操作结果:销毁线性表L

LinkList q;

while(L)

{

q=L->next;

free(L);

L=q;

}

}

void ClearList(LinkList L) // 不改变L

{ // 初始条件:线性表L已存在。操作结果:将L重置为空表

LinkList p,q;

p=L->next; // p指向第一个结点

while(p) // 没到表尾

{

q=p->next;

free(p);

p=q;

}

L->next=NULL; // 头结点指针域为空

}

Status ListEmpty(LinkList L)

{ // 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE

if(L->next) // 非空

return FALSE;

else

return TRUE;

}

int ListLength(LinkList L)

{ // 初始条件:线性表L已存在。操作结果:返回L中数据元素个数

int i=0;

LinkList p=L->next; // p指向第一个结点

while(p) // 没到表尾

{

i++;

p=p->next;

}

return i;

}

Status GetElem(LinkList L,int i,ElemType &e) // 算法2.8

{ // L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR

int j=1; // j为计数器

LinkList p=L->next; // p指向第一个结点

while(p&&j

{

p=p->next;

j++;

}

if(!p||j>i) // 第i个元素不存在

return ERROR;

e=p->data; // 取第i个元素

return OK;

}

int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))

{ // 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)

// 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。

// 若这样的数据元素不存在,则返回值为0

int i=0;

LinkList p=L->next;

while(p)

{

i++;

if(compare(p->data,e)) // 找到这样的数据元素

return i;

p=p->next;

}

return 0;

}

Status PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e)

{ // 初始条件: 线性表L已存在

// 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,

// 返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE

LinkList q,p=L->next; // p指向第一个结点

while(p->next) // p所指结点有后继

{

q=p->next; // q为p的后继

if(q->data==cur_e)

{

pre_e=p->data;

return OK;

}

p=q; // p向后移

}

return INFEASIBLE;

}

Status NextElem(LinkList L,ElemType cur_e,ElemType &next_e)

{ // 初始条件:线性表L已存在

// 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,

// 返回OK;否则操作失败,next_e无定义,返回INFEASIBLE

LinkList p=L->next; // p指向第一个结点

while(p->next) // p所指结点有后继

{

if(p->data==cur_e)

{

next_e=p->next->data;

return OK;

}

p=p->next;

}

return INFEASIBLE;

}

Status ListInsert(LinkList L,int i,ElemType e) // 算法2.9。不改变L

{ // 在带头结点的单链线性表L中第i个位置之前插入元素e

int j=0;

LinkList p=L,s;

while(p&&j

{

p=p->next;

j++;

}

if(!p||j>i-1) // i小于1或者大于表长

return ERROR;

s=(LinkList)malloc(sizeof(LNode)); // 生成新结点

s->data=e; // 插入L中

s->next=p->next;

p->next=s;

return OK;

}

Status ListDelete(LinkList L,int i,ElemType &e) // 算法2.10。不改变L

{ // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值

int j=0;

LinkList p=L,q;

while(p->next&&j

{

p=p->next;

j++;

}

if(!p->next||j>i-1) // 删除位置不合理

return ERROR;

q=p->next; // 删除并释放结点

p->next=q->next;

e=q->data;

free(q);

return OK;

}

void ListTraverse(LinkList L,void(*vi)(ElemType))

// vi的形参类型为ElemType,与bo2-1.cpp中相应函数的形参类型ElemType&不同

{ // 初始条件:线性表L已存在。操作结果:依次对L的每个数据元素调用函数vi()

LinkList p=L->next;

while(p)

{

vi(p->data);

p=p->next;

}

printf("\n");

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值