带头结点单链表的内存分布情况
头文件
#pragma once
//带头节点的单链表
//单链表尾节点的next为NULL
//List为一条链表;Node* 一个节点的地址
typedef struct Node
{
int data;//数据
Node *next;//下一个节点的地址
}Node ,*List ;//List == Node *
//初始化
void InitList(List plist);
//头插法
bool Insert_head(List plist,int val);
//尾插法
bool Insert_tail(List plist,int val);
//在pos下标插入数据val
bool Insert_pos(List plist,int pos,int val);
//查找,找到返回节点地址,没有找到返回NULL
Node *Search(List plist,int key);
//删除第一个key对应的节点
bool Delete(List plist,int key);
//删除第一个数据节点,并通过rtval获得删除的值
bool Delete_head(List plist,int *rtval);
//删除最后一个数据节点,并通过rtval获得删除的值
bool Delete_tail(List plist,int *rtval);
//获取长度,统计数据节点的个数
int GetLength(List plist);
//判空
bool IsEmpty(List plist);
//清除所以数据
void Clear(List plist);
//销毁所有节点
void Destroy(List plist);
//打印
void Show(List plist);
cpp文件
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"list.h"
//初始化
void InitList(List plist)
{
assert(plist != NULL);
plist->next = NULL;
}
//头插法
bool Insert_head(List plist,int val)
{
assert(plist != NULL);
Node *p = (Node*)malloc(sizeof(Node));
p->data = val;
p->next = plist->next;
plist->next = p;
return true;
}
//尾插法
bool Insert_tail(List plist,int val)
{
assert(plist != NULL);
Node * p = (Node*)malloc(sizeof(Node));
assert( p != NULL);
if(p == NULL)
{
return false;
}
Node *q;
for(q=plist;q->next != NULL;q = q->next);
//把p 插到 q 的后边
p->next = q->next;
q->next = p;
p->data = val;
//p->next = NULL;
return true;
}
//在pos下标插入数据val
bool Insert_pos(List plist,int pos,int val)
{
if(pos < 0)
{
return false;
}
Node *p = (Node*) malloc (sizeof(Node));
Node *q = plist;
int i = 0;
for(;q->next!= NULL && i<pos;i++,q = q->next);
if(i< pos )//判断是否连续
{
return false;
}
p->next = q ->next;
q->next = p;
p->data = val;
}
//查找,找到返回节点地址,没有找到返回NULL
Node* Search(List plist,int key)
{
Node *p;
for(p =plist->next;p != NULL;p=p->next)
{
if(p->data == key )
{
return p ;
}
}
//return false;
return NULL;
}
//查找key的前趋节点
static Node *SearchPri(List plist,int key)
{
Node* p = (Node*) malloc (sizeof(Node));
for(p = plist;p ->next != NULL; p = p->next)
{
if(p->data == key)
{
return p;
}
}
return NULL;
}
//删除第一个key对应的节点
bool Delete(List plist,int key)
{
Node *p;
p = SearchPri(plist, key);//p是查找的key对应的前驱
if(p == NULL)
{
return false;
}
Node* q = p->next;//q 指向将要删除的节点
p->next = q->next;//将q从链表中剔除
free(q);//释放q
}
//删除第一个数据节点,并通过rtval获得删除的值
bool Delete_head(List plist,int *rtval)
{
assert(plist != NULL);
if(plist != NULL || plist->next == NULL)
{
return false;
}
if(rtval != NULL)
{
*rtval = plist->data;
}
Node * p = plist ->next;
plist->next = p->next;
free(p);
}
//删除最后一个数据节点,并通过rtval获得删除的值
bool Delete_tail(List plist,int *rtval)//******************************
{
assert(plist != NULL);
if(plist == NULL || plist->next == NULL)
{
return false;
}
Node *p;
for(p =plist;p ->next!= NULL; p = p->next);
if(rtval != NULL)
{
*rtval = p->next->data;
}
p ->next = NULL;
free(p);
return true;
}
//获取长度,统计数据节点的个数
int GetLength(List plist)
{
int length = 0;
for(Node *p =plist->next;p != NULL ;p = p->next)
{
length ++;
}
return length;
}
//判空
bool IsEmpty(List plist)
{
assert(plist != NULL);
if(plist == NULL)
{
return false;
}
return plist->next == NULL;
}
//清除所有数据
void Clear(List plist)
{
Destroy(plist);
}
//销毁所有节点
void Destroy(List plist)
{
assert(plist != NULL);
if(plist == NULL)
{
return ;
}
while(plist ->next != NULL)
{
Node *p = plist->next;
plist ->next= p->next;
free(p);
}
}
//打印
void Show(List plist)
{
assert(plist != NULL);
if(plist == NULL)
{
return ;
}
for(Node*p = plist ->next;p != NULL;p = p->next)
{
printf("%d ",p->data);
}
printf("\n");
}
主函数
#include<stdio.h>
#include"list.h"
int main()
{
Node list1;
Node list2;
InitList(&list1);
for(int i= 0;i<10;i++)
{
Insert_tail( &list1,i);
}
Show(&list1);
InitList(&list2);
for(int i= 0;i<10;i++)
{
Insert_head( &list2,i);
}
Show(&list2);
int rt = -1;
printf("%d\n",Delete_tail(&list2,&rt));
printf("%d\n",&rt);
Destroy(&list1);
Show(&list1);
Destroy(&list2);
Show(&list2);
return 0;
}