todo: 释放内存失败
功能实现
- 结构体
- 初始化
- 构建(头插 / 尾插)
- 获取某个位置上的结点数据
- 遍历输出
- 删除(无法释放结点,求助)
- 插入
/*线性表链式存储结构*/
#include <stdio.h>
#include <stdlib.h> //pause 的头文件
#include <time.h> // 使用当前时钟做种子
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define INIT_LISTSIZE 5 //链表的初始数据分配量
#define MAXSIZE 20 //存储空间初始分配量
typedef int Status;//Status 是函数的类型,其值是函数结果状态代码 如OK
typedef int ElemType;//ElemType类型根据实际情况定
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
// 定义LinkList
typedef struct Node *LinkList;
/*初始化*/
void InitList_Sq(LinkList L)
{
//L->data = (ElemType)malloc(sizeof(ElemType));
L->next = NULL;
}
/*尾插法*/
void InitWithDatasTail(LinkList L)
{
// 初始化5个数据量
int k;
LinkList temp;
LinkList p,r; // 代操作L
p = L;
r=L;
//temp->next = NULL;
srand((unsigned)time(NULL));
for(k = 0;k<INIT_LISTSIZE;k++)
{
temp = (LinkList)malloc(sizeof(LinkList)); // 不可以放在外面 否则最后只会有一个数据结点
temp->data = rand();
p->next = temp;
p = p->next;
}
p->next=NULL;
}
/*头插法:可以直接使用L进行操作,不用再拟定p*/
void InitWithDatasFront(LinkList L)
{
int k;
LinkList temp,p;
p = L;
srand((unsigned)time(NULL));
for (k = 0;k<INIT_LISTSIZE;k++)
{
temp = (LinkList)malloc(sizeof(LinkList));
temp->data = rand();
temp->next=p->next;
p->next = temp;
}
}
/**
获取第i个结点
1. 声明一个结点P指向链表的第一个结点,初始化j从1开始
2. 当j<i时,遍历链表,让p的指针向后移动,不断指向下一个结点,j++
3. 若到链表末尾p为空,则说明第i个元素不存在
4. 否则查询成功,返回结点p的数据
*/
Status GetElem(LinkList L,int i,ElemType *e)
{
int j; // 用于计数
LinkList p; // 让p指向链表L的第一个数据结点
p = L->next; // 指向第一个数据结点
j = 1; // 表示第j个结点
while (p && j<i) // p不为空(未到最后一个结点)
{
p = p->next;
j++;
}
if(!p || j>i)
{
return ERROR;
}
*e = p->data;
printf("获取到的第%d个元素的值为%d\n\n",i,*e);
return OK;
}
/*输出函数*/
void PrintList(LinkList L)
{
LinkList p;
printf("开始遍历\n");
for(p = L->next;p!=NULL;p = p->next)
{
printf("%d ",p->data);
}
printf("\n遍历结束\n\n");
}
int GetLength(LinkList L)
{
int length;
LinkList p;
length=0;
for(p=L->next;p;p=p->next,length++);
printf("表长为%d\n\n",length);
return length;
}
// todo 为什么无法释放
//Status ListDelete(LinkList *L,int i,ElemType *e)
//{
// int k;
// LinkList p,q;
// p = *L;
// if(!(*L))
// {
// printf("L为空");
// return ERROR;
// }
// if (i<=0)
// {
// printf("i的值不合法");
// return ERROR;
// }
// // 跳出循环的时候为 第 i-1个结点 或者超出范围
// for ( k = 0; p->next && k < i-1; k++)
// {
// p = p->next;
// }
// if(!p->next)
// {
// printf("i超出范围\n");
// return ERROR;
// }
// q = p->next;
// *e = q->data;
// p->next=q->next;
// printf("被回收的结点值为%d\n\n",*e);
//
// // 释放
// //free(q);
// return OK;
//}
Status ListDelete(LinkList L,int i,ElemType *e)
{
int k;
LinkList p,q;
p = L;
if(!(L))
{
printf("L为空");
return ERROR;
}
if (i<=0)
{
printf("i的值不合法");
return ERROR;
}
// 跳出循环的时候为 第 i-1个结点 或者超出范围
for ( k = 0; p->next && k < i-1; k++)
{
p = p->next;
}
if(!p->next)
{
printf("i超出范围\n");
return ERROR;
}
q = p->next;
*e = q->data;
p->next=q->next;
printf("被回收的结点值为%d\n\n",*e);
// 释放
//free(q);
return OK;
}
/*插入*/
Status ListInsert(LinkList *L,int i,ElemType e)
{
int k;// 记录循环次数
LinkList p,q;
k = 1;
p = *L;
if (i<=0)
{
printf("i的值不合理\n\n");
return ERROR;
}
// 跳出循环的时候 [p为空] 或 [k=i,此时p指向第i-1个数据结点]
for(;p!=NULL&&k<i;k++)
{
p= p->next;
}
if (!p)
{
printf("i的值超出\n\n");
return ERROR;
}
q=(LinkList)malloc(sizeof(LinkList));
q->data = e;
if (p->next)
{
q->next = p->next->next;
}else
{
q->next=NULL;
}
p->next = q;
return OK;
}
void main()
{
LinkList L = (LinkList)malloc(sizeof(LinkList));
ElemType e;
e = (ElemType )malloc(sizeof(ElemType));
// 初始化
InitList_Sq(L);
// 数据
InitWithDatasFront(L);
// 输出
PrintList(L);
// 获取测试
//GetElem(L,5,e);
// 表长测试
GetLength(L);
// 删除测试
ListDelete(L,5,&e);
PrintList(L);
// 插入测试
ListInsert(&L,0,336);
PrintList(L);
// 链表长度
GetLength(L);
system("pause");
}