今天主要了解了数据结构,什么叫数据结构,以及数据结构中的单向链表
数据结构
1.数据结构的定义:
一组用来保存一种或者多种特定关系的数据的集合(组织和存储数据)
程序的设计:将现实中大量而复杂的问题以特定的数据类型和特定的存储结构存储在内存中,
并在此基础上实现某个特定的功能的操作;
程序 = 数据结构 + 算法
2.数据与数据之间的关系
数据的逻辑结构:数据元素与元素之间的关系
集合:关系平等
线性结构:元素之间一对一的关系(表(数组,链表),队列。栈。。。)
树型结构:元素之间一对多的关系(二叉树)
图形结构:元素之间多对多的关系(网状结构)
数据的物理结构:数据的逻辑结构在计算机内存中的存储形式
顺序存储:采用一段连续的内存空间保存元素
优点:空间连续,访问方便
缺点:插入删除需要移动大量的元素
需要预分配内存空间
容易造成存储空间碎片
链式存储:采用一组非连续的内存空间保存元素
缺点:访问元素效率低
优点:插入和删除数据方便
不需要预分配内存
索引存储:通过关键字构建索引表,通过索引表来来找到数据的存储位置
散列存储(哈希存储):将数据元素的存储位置与关键码之间建立确定对
应关系从而实现查找的存储方式
单向链表
在单向链表中,我主要完成了对于链表的头插、尾插、头删、尾删、遍历、查找、销毁以及修改。
下面我将举一个例子:其中有main.c link.c link.h三个文件
link.h 头文件
#ifndef __LINK_H__
#define __LINK_H__
#include<stdio.h>
#include<stdlib.h>
typedef int DATA_TYPE; //存储的数据的数据类型
typedef struct linknode //链表的结点类型
{
DATA_TYPE node; //数据域
struct linknode *pnext; //指针域
}LINK_NODE;
typedef struct linklist //描述链表属性的标签类型
{
struct linknode *phead; //存储头结点地址的指针
DATA_TYPE clen; //链表中当前结点个数
}LINK_LIST;
extern LINK_LIST *CreatLinkList(); //创建链表属性
extern int PushHeadLink(LINK_LIST *plist,DATA_TYPE node); //头插
extern int PushTailLink(LINK_LIST *plist,DATA_TYPE node); //尾插
extern int ErgodicLink(LINK_LIST *plist); //遍历
extern int PopHeadLink(LINK_LIST *plist); //头删
extern int PopTailLink(LINK_LIST *plist); //尾删
extern int DestroyLink(LINK_LIST *plist); //销毁
extern LINK_NODE *FindLink(LINK_LIST *plist,DATA_TYPE node);//查找
extern int EditLink(LINK_LIST *plist,LINK_NODE *pnode,DATA_TYPE node); //修改
#endif
main.c
#include"link.h"
int main(void)
{
LINK_LIST *plist = NULL;
LINK_NODE *pfind = NULL;
plist = CreatLinkList();
if(NULL == plist)
{
perror("fail to CreatLinkList");
return -1;
}
PushHeadLink(plist,1); //头插
PushTailLink(plist,33); //尾插
PushTailLink(plist,22);
PushTailLink(plist,11);
pfind = FindLink(plist,8); //查找,获得值的地址
printf("%#x\n",pfind);
EditLink(plist,pfind,32); //修改
ErgodicLink(plist); //遍历
PopTailLink(plist); //尾删最后一个
DestroyLink(plist); //销毁
return 0;
}
link.c
#include "link.h"
LINK_LIST *CreatLinkList() //创建链表属性,包括头指针以及链表中节点个数
{
LINK_LIST *plist = malloc(sizeof(LINK_LIST));
if(NULL == plist)
{
perror("fail to malloc");
return NULL;
}
plist->phead = NULL;
plist->clen = 0;
return plist;
}
int PushHeadLink(LINK_LIST *plist,DATA_TYPE node) //头插
{
LINK_NODE *pmode = malloc(sizeof(LINK_NODE));
if(NULL == pmode)
{
perror("fail to malloc");
return -1;
}
pmode->node = node;
pmode->pnext = plist->phead;
plist->phead = pmode;
plist->clen++;
return 0;
}
int PopHeadLink(LINK_LIST *plist) //头删
{
LINK_NODE *ptmp = plist->phead;
if(NULL == ptmp)
{
return 0;
}
else
{
plist->phead = ptmp->pnext;
free(ptmp);
}
plist->clen--;
return 0;
}
int PopTailLink(LINK_LIST *plist) //尾删
{
LINK_NODE *ptmp = plist->phead;
if(NULL == ptmp)
{
return 0;
}
else if(NULL == ptmp->pnext)
{
plist->phead = NULL;
free(ptmp);
}
else
{
while(ptmp->pnext->pnext)
{
ptmp = ptmp->pnext;
}
ptmp->pnext = NULL;
free(ptmp->pnext);
}
plist->clen--;
return 0;
}
int PushTailLink(LINK_LIST *plist,DATA_TYPE node) //尾插
{
LINK_NODE *ptmp = plist->phead;
LINK_NODE *p = malloc(sizeof(LINK_NODE));
if(NULL == p)
{
perror("fail to malloc");
return -1;
}
p->node = node;
p->pnext = NULL;
if(NULL != ptmp)
{
while(ptmp->pnext != NULL)
{
ptmp = ptmp->pnext;
}
ptmp->pnext = p;
}
else
{
plist->phead = p;
}
plist->clen++;
return 0;
}
int DestroyLink(LINK_LIST *plist) //销毁链表
{
LINK_NODE *p = plist->phead;
if(NULL == p)
{
return 0;
}
else
{
while(p)
{
plist->phead = p->pnext;
free(p);
p = plist->phead;
}
}
return 0;
}
int ErgodicLink(LINK_LIST *plist) //遍历
{
LINK_NODE *p = plist->phead;
while(p)
{
printf("%d\n",p->node);
p = p->pnext;
}
return 0;
}
LINK_NODE *FindLink(LINK_LIST *plist,DATA_TYPE node) //查找
{
LINK_NODE *p = plist->phead;
if(NULL == p)
{
return NULL;
}
else
{
while(p)
{
if(p->node == node)
{
break;
}
p = p->pnext;
}
}
return p;
}
int EditLink(LINK_LIST *plist,LINK_NODE *pnode,DATA_TYPE node) //修改
{
LINK_NODE *ptmp = plist->phead;
if(NULL == ptmp)
{
return 0;
}
else
{
while(ptmp)
{
if(ptmp == pnode)
{
ptmp->node = node;
break;
}
ptmp = ptmp->pnext;
}
}
return 0;
}