【C++基础复习01】结构体和链表
2017-12-16 14:16
435 查看
结构体
结构体是一个可以包含不同数据类型的一个结构,使用修饰符struct进行定义。结构体可以在一个结构中声明不同的数据类型,并且只有结构相同的结构体变量可以相互赋值。
先来看例子,如下构造一个结构体:
struct student { int id; char name[9]; int Chinese,math,English; double average; };
以上就是由个人定义的一个结构体student,其中的属性(id,Chinese,average)等被称之为结构体成员,并且有自己的数据类型。需要注意的是,在{}结尾处,要加上一个分号 ; 否则会导致语法错误。另外,描述的结构体并不占用内存空间,只有当用这种新的数据类型定义变量,数组,申请变量或申请堆数组时候才要分配空间。
接下来我们利用这个结构体来创建一些变量并来访问,代码片段如下:
student s; //建立一个student对象 student *ps=&s; //定义一个指针变量指向s student &rs=s; //定义一个引用(不占用空间) s.id=1; strcpy(s.name,"李诗珺"); //利用字符串复制对s.name赋值,不能用s.name="XX" ps->Chinese=95; //用指针变量访问目标对象成员 (*ps).math=90; //等价于 ps->math=90 s.English=92; rs.average=(s.Chinese+rs.English+ps->math)/3.0; //引用访问“绑定”的目标对象成员 cout<<s.name<<"的平均成绩为"<<s.average<<endl;
需要注意的是,优先级为2的圆点运算符“.”用于结构体对象访问其成员;箭头运算符“->”用于结构体指针访问目标对象成员。这样一来,基本就掌握了结构体的基本用法了。
单向链表
在理解了结构体的基础上,再来认识链表就比较容易了。能够单方向联络的连接方式被称为单向链表,构成单向链表的元素被称为结点。结点应该具有承载数据及指向下一个结点的能力。在链式连接结构中,删除某个结点只需要将该节点保存的下一个结点地址“交给”上一个结点即可。由于结点个数以及各个结点在内存中的地址都很容易得到,所以将单向链表传递给函数时,只需要传递链首地址。先来试着定义一个结点:
struct memory //定义内存空间结点 { int address; //分区首地址 int space; //空间大小 bool status; //状态位 memory *next; //同类指针,指向下一个内存空间的地址 };
以上便定义了一种型的数据类型,先来创建一条空链表:
memory *head=NULL;
创建完毕之后,就要对这条单向链表进行操作了。首先得加入元素,也就是在首节点处再插入结点,插入函数如下:
void InsertBeforeHead(memory *&head,int space,bool status,int address) { memory *p=new memory ; //创建一个新结点 p->address=address; p->space=space; //赋值操作 p->status=status; p->next=head; //新结点将原链首结点当成下一个结点 head=p; //head记录新结点的地址,成为新的链首地址 //最先定义的head到最后会成为链尾 }
在链表创建完成之后(一般创建空链表),然后利用上述函数添加一个新结点到链首前成为新的链首。当插入完成之后,就完成了一条单链表的创建。接下来附上一些常用的链表操作函数。
删除链首结点的函数:
void DeleteHead(memory *&head) //这里需要使用引用,因为要直接修改head的指向 { memory *p=head; //记录当前链首结点地址 if(head!=NULL) //判断是否为空链表 { head=head->next; //下一个结点成为新的链首结点,相当于删除了当前结点 delete p; //释放原链首结点 } }
遍历函数的运用:
memory *p; int n; //统计结点个数 for(p=head;p!=NULL;p=p->next) { n++; //统计计算 cout<<p->space<<endl; //遍历输出数据 }
释放所有结点:
while(head!=NULL) { p=head; head=head->next; //使head指向的下一个结点成为头结点 delete p; //释放空间 }
插入一个结点:
void Insert(int i,int e,int n,memory *&head) //i表示插入位置,e表示插入的数据,n表示结点个数 { memory *q=new memory ; //创建一个新结点,即为要插入的结点 memory *p; //用于遍历结点 q->space=e; //赋值 q->status=0; q->address=0; if(i>n||i<0) //判断是否越界 return ; if(i==1) //即插入位置为头结点 { q->next=head; //成为链首 head=q; } for(p=head;i!=0,p!=NULL;p=p->next,i--); //找到插入的位置 if(i==n) //即插入位置为链尾 { p->next=q; //直接在链尾插入 } else { q->next=p->next; //q代替本来p的位置,指向p的下一个元素 p->next=q; //p的下一个结点指向q } }
删除一个结点:
void DeleteHead2(int e,memory *&head) //e用来确定删除哪个结点 { memory *p,*q; p=head; //前哨结点 q=head->next; //用于定位需要删除的结点 while(q!=NULL) { if(q->space==e) //找到该结点 { p->next=q->next; //使待删结点脱链 delete q; break; } p=p->next; //若未找到,则往前推进一个结点 q=q->next; } }
以上是单向链表的一些基础操作函数,掌握了这些就基本能够对单向链表进行增删查改的操作了。
双向链表
从上文的单向链表中可以看出,单向链表只有指向下一个结点的指针,并不能访问其前驱元素,所以在访问单链表的时候,只能顺序访问,但在实际操作中,可能是一件比较麻烦的事情,所以接下来要来学习一下双向链表。说来双向链表其实很简单,无非是在之前的单向链表之前加入一个前驱指针pre,后继指针next不变。这样,无论是顺序遍历还是逆序遍历都很方便,可以快速找到上一个结点的位置。
首先来看一下如何定义双向链表的结点:
struct node { int data; node* prev; //前驱指针 node* next; //后继指针 };
那这样看来,双向链表的头结点前驱指针为空,尾结点的后继指针为空,也非常好判断。
结合单向链表实现的代码,双向链表也非常容易实现,而比较容易犯错的地方就是添加和删除结点,其他代码省略了,接下来附上几段伪代码,实现添加和删除结点。
添加元素:
我们假设要插入的结点为node,插入位置的结点为current,插入位置的下一个结点为next。
current->next=node; node->prev=current; node->next=next; next->prev=node;
代码并不难,但要理解。要求是将node插入current和next结点之间,那么要修改的指针就是:current的后继,next的前驱,以及node的前驱和后继。我们要让current的后继指向node,让next的前驱指向node,这样就能找到node的位置了。接下来修改node的前驱后继指针,分别指向current和next,就完整了。
删除结点:
我们假设要删除的结点为node,前驱结点为current,后继结点为next.
current->next=next; next->prev=current; delete node;
删除结点相对于插入结点更简单,只需要修改要删除结点的前驱结点和后继结点的指针即可。将前驱结点的后继指向后继结点,然后将后继结点的前驱指向前驱结点,最后别忘记释放node的空间。这样就完成了删除结点的操作。
其他的查询修改操作也比较容易实现,这里笔者就不再赘述了。能够了解上述的函数操作,那在单链表以及双向链表的操作方面,应该都不会有问题了。
相关文章推荐
- c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系
- Professional C++ 01 A Crash Course in C++ 快速的C++基础知识复习
- 标准C++_01_编程基础
- c++基础值链表基本操作
- C++基础-链表的建立、插入和删除
- C++基础01
- 复习C++一些基础知识
- C++基础复习心得3
- 【C++基础】----运算符重载(01)
- .Net学习笔记----2015-07-08(基础复习和练习01)
- JS一起学01:css复习、js基础知识、事件、参数、函数、网页换肤、if判断、className问题、浏览器执行顺序
- C++复习笔记01
- 自己的C++复习进阶之路基础学习教程
- 结构体与共用体01 - 零基础入门学习C语言53
- C++基础复习
- C++基础复习之this关键字
- C/C++常见的笔试面试题-01(编程基础)
- C++基础复习心得2
- 【C++】笔记四:C++类通俗点说—— C结构体复习
- Java基础复习01