基础:结构体,数组,指针。
本文编译环境:Dev c++ 5.4.0
语言:c
序言:结构创建时候的typedef的作用!!!在c和c++不一样
在C中,必须用typedef,声明时就可以用 别名定义一个变量;
而在C++中,有两种方式,
方式一:不需要typedef即可定义,访问直接用别名访问数据,
方式二:用typedef定义,访问必须先用别名定义变量,再访问数据。
对 线性表的操作主要有,创建,求长,查找,插入,删除和显示。
先说顺序储存,其实就是利用数组来建立线性表,下面展示下顺序表的六个操作。
#define MAXLEN 100
#define datatype int
//结构体的建立
typedef struct
{
datatype data[MAXLEN];//数据存储
int last;//指向最后一个元素,-1为初始值
}Seqlist;//名字
//顺序表创建
Seqlist *Createlist()
{
Seqlist *Lq;//定义头指针
Lq=(Seqlist *)malloc(sizeof(Seqlist));//给头指针分配空间
Lq->last=-1;//last的初始化
return Lq;//返回头指针
}
//求长直接last+1就可以了
//查找元素
int Findlist(Seqlist *Lq,datatype i)//引入头指针和被查元素
{
int j;
for(j=0;j<=Lq->last;j++)
{
if(Lq->data[j]==i) return j;//返回被查元素出现的第一次位置
}
return -1;//没有相匹配返回查找失败
}
//插入元素
int Insertlist(Seqlist *Lq,int i,datatype x)//引入头指针,被插元素的位置和被插元素
{
int j;
if(Lq->last==MAXLEN||i<0||i>Lq->last+1) return -1;//插入元素位置有误或者已满,报错
for(j=Lq->last+1;j>i+1;j--)
{
Lq->data[j]=Lq->data[j-1];//被插入元素位置的往后所有元素往后移动
}
Lq->data[i]=x;//插入元素
Lq->last++;//数据长度加1
return 1;//返回成功
}
//删除元素
int Insertlist(Seqlist *Lq,int i)//引入头指针,被删元素的位置
{
int j;
if(i<0||i>Lq->last) return -1;//删除元素位置有误报错
for(j=i;j<Lq->last;j++)
{
Lq->data[j]=Lq->data[j+1];//被删除元素位置,被后一位占据
}
Lq->last--;//数据长度减1
return 1;//返回成功
}
//显示所有元素
void Looklist(Seqlist *Lq)//引入头指针,被删元素的位置
{
int j;
for(j=0;j<=Lq->last;j++)
{
printf("%d",Lq->data[j]);//输出
}
}
线性表就是个数组操作,删除和插入操作部分利用循环进行数据覆盖,优点是创建简单,缺点是局限性很大,必须先开垦一部分内存,不管用没用的到,而且很容易溢出。再比较下一个方法这些缺点就解决掉了。
相比线性表,线性链表就显得重要的多,这里强调一下线性链表的六个操作方法。
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 100
#define datatype int
//结构体的建立
typedef struct link
{
datatype data;//数据存储
struct link *next;//指向下一个节点
}Seqlist,*Seqlink;//名字
//线性链表创建,这个方法意义不大,但是重要的是个思想
Seqlist *Createlist()
{
link *head;//定义头指针
head=(link *)malloc(sizeof(link));//分配存储空间
return head;//返回头指针
}
//求长
int Lenlist(link *head)//引入头指针
{
int i=0;//计数器
while(head!=NULL)
{
i++;//不为空计数器加1
head=head->next; //往下递增
}
return i;//返回长度
}
//查找
Seqlist *Searchlist(Seqlist *head,datatype x)//引入头指针和被查找元素
{
while(head!=NULL)
{
if(head->data==x) return head;//找到返回指针
head=head->next;//遍历下一个
}
return NULL;//返回为空
}
//删除
Seqlist *Deletelist(Seqlist *head,datatype x)//引入头指针和被删除元素
{
Seqlist *p,*s;
s=head;//存放头指针
while(head!=NULL)
{
if(head->data==x)
{
p->next=head->next;//让当前的上一步指针指向当前的下一步指针
free(head);//释放被删除的指针资源
return s;//返回删除完成后的头指针
}
p=head;//在遍历下一个之前,先存起来,等到下一步,这个就是上一步的指针
head=head->next;//遍历下一个
}
return NULL;//返回为空
}
//显示
void Looklist(Seqlist *head)//引入头指针
{
while(head!=NULL)
{
printf("%d\n",head->data);//输出
head=head->next;//遍历下一个
}
}
int main(int argc, char *argv[]) {
int i;
Seqlist *head=NULL,*b;
for(i=0;i<5;i++)
{
Seqlist *a=(link *)malloc(sizeof(link));
a->data=i;
a->next=head;
head=a;
}
Looklist(head);//查看当前指针所有内容
//printf("%d\n",Lenlist(head));//输出当前长度
//printf("%d",Searchlist(head,3)->data);//输出被查找元素的值
Looklist(Deletelist(head,3));//删除后并可以查看
return 0;
}
这里在线性链表的基础上再补充一下,循环链表和双向链表。
循环链表:将线性的单向链表最后一个节点的指针域指向头节点,整个链表头尾节点相连形成一个环,就构成了单循环链表。
双向链表:
//结构体的建立
typedef struct link
{
datatype data;//数据存储
struct link *front;//指向前一个结点
struct link *rear;//指向后一个结点
}Seqlist,*Seqlink;//名字差别就在,访问某个结点时候,可以直接访问上一个或者下一个结点。
在学习这个线性链表时候,有个思想是不同于线性表的,就是线性链表是从头部进行操作的,其添加也是从头部添加,这里需要注意下(下划线部分的操作,需要深刻理解)。
这些代码都是跑过的,建议大家还是自己亲手敲一遍加深印象,作者这里也是一字一字敲出来的,要避免眼高手低。
本章的内容大家可以私信我,我也会第一时间回复大家的,差不多暑假两个月,复习下这些基本知识,其他的问题也可以问我,就算我不知道的,在能力范围之内的一定竭尽全力为你们解答。我的QQ:932824098.