数据结构
如何组织存储数据
程序 = 数据结构 + 算法
MVC:软件设计结构
M:数据的管理(数据结构)
V:视图,数据的反映及人机交互
C:逻辑控制
单向链表
有头链表:第一个链表结点中不存储有效数据
无头链表:第一个链表结点中存储有效数据
需掌握的七大操作
初始化链表
typedef int DATA_TYPE; //将整形重命名
/* 链表的结点类型 */
typedef struct node
{
DATA_TYPE data; //数据域
struct node *pnext; //指针域
}LINK_NODE;
/* 描述链表属性的标签的类型 */
typedef struct list
{
LINK_NODE *phead; //存放头结点的地址
int clen; //结点个数
}LINK_LIST;
建立一个空链表
LINK_LIST *create_linked(void)
{
LINK_LIST *plist = NULL;
plist = malloc(sizeof(LINK_LIST)); //创建一个链表标签的空间
if (NULL == plist)
{
perror("fail to malloc");
return NULL;
}
plist->phead = NULL; //标签指针域所指向的头结点的地址为空
plist->clen = 0; //标签含有的节点个数为0;
return plist;
}
链表的头插
int Insert_Linked_List(LINK_LIST *plist, DATA_TYPE data)
{
LINK_NODE *pnode = NULL;
pnode = malloc(sizeof(LINK_NODE)); //创建一个新结点的空间
if (NULL == pnode)
{
perror("fail to malloc");
return -1;
}
pnode->data = data; //给新结点的数据域赋值
pnode->pnext = NULL; //给新结点的指针域指向为空,成为尾结点
pnode->pnext = plist->phead; //将头结点的地址放到新创建的结点的指针域中
plist->phead = pnode; //将新创建的结点的地址放到标签的指针域中
plist->clen++; //标签的结点数自增
return 0;
}
遍历打印
int Ergodic_Linkde_List(LINK_LIST *plist)
{
LINK_NODE *pmt = NULL; //定义一个指向每一个结点的指针
pmt = plist->phead; //指向头结点
while (pmt != NULL)
{
printf("%d\n", pmt->data); //打印指针指向结点的
pmt = pmt->pnext; //将每个结点的指针域的内容赋值给这个指针
}
return 0;
}
判断是否位空链表
int is_empty_link(LINK_LIST *plist)
{
return NULL == plist->phead;
}
链表的尾插
int Tail_Plug_List(LINK_LIST *plist, DATA_TYPE data)
{
LINK_NODE *pnode = NULL;
LINK_NODE *ptme = NULL;
pnode = malloc(sizeof(LINK_NODE));
if (NULL == pnode)
{
perror("fail to malloc");
return -1;
}
pnode->data = data;
pnode->pnext = NULL;
if (is_empty_link(plist)) //链表为空直接在后面插入
{
plist->phead = pnode;
plist->clen++;
return 0;
}
ptme = plist->phead; //链表非空
while(ptme->pnext != NULL) //找到尾链表在以次插入
{
ptme = ptme->pnext;
}
ptme->pnext = pnode;
plist->clen++;
return 0;
}
链表的尾删
int Tail_Deletion_List(LINK_LIST *plist)
{
LINK_NODE *ptme = NULL;
if (is_empty_link(plist)) //为空链表时
{
return 0;
}
else if(1 == plist->clen) //只有一个结点时
{
free(plist->phead);
plist->phead = NULL;
}
else //一个以上结点时
{
ptme = plist->phead;
while(ptme->pnext->pnext != NULL)
{
ptme = ptme->pnext; //指针指到尾结点的前驱结点
}
free(ptme->pnext);
ptme->pnext = NULL;
}
plist->clen--;
return 0;
}
链表的头删
int Head_Delete(LINK_LIST *plist)
{
LINK_NODE *ptme = NULL;
if (is_empty_link(plist)) //空链表不用删除
{
return 0;
}
else if (1 == plist->clen) //只有一个结点时,直接删除
{
free(plist->phead);
plist->phead = NULL;
}
else //不止一个结点
{
ptme = plist->phead->pnext; //将第二个结点的地址存起来
free(plist->phead); //free掉第一个
plist->phead = ptme; //将第二个结点的地址放到标签中
}
plist->clen--; //个数--
return 0;
}