直接附代码慢慢看;
编程工具: vs2015,主要语言c++。
数据结构: 大话数据结构
#include <iostream>
#include <time.h>
using namespace std;
#pragma region 状态申明
#define ok 1
#define error 0
#define MAXSIZE 20
typedef int Status; //函数的返回状态(int),实际不一定
typedef int ElemType;// 同理
typedef struct Node
{
ElemType data;
struct Node *next; //指向自己的一个指针
}Node;
typedef struct Node *LinkList; //单向链表
#pragma endregion
#pragma region 初始化函数
Status ListInit(LinkList *L) //初始化
//需要把目标初始化,故需要传指针
{
try
{
*L = new Node;
(*L)->next = NULL;
}
catch (const std::exception&)
{
return error;
}
}
Status ListOutput(LinkList L) //打印输出
{
LinkList p = L->next;//第一个节点
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
return ok;
}
Status ListLength(LinkList L) //返回长度
{
int i=0;
while (L->next)
{
i++;
L = L->next;
}
return i;
}
#pragma endregion
#pragma region 增删改查
Status GetElem(LinkList L, int i, ElemType *e) //查看元素
//只是查看值,L不需要改变,不用传地址
{
int j = 1;
LinkList p = L->next;//第一个节点
while (p && j<i) //判断位置,链表是否为空(未分配空间)
{
p = p->next;
++j;
}
if (!p || j > i) //为空或者第i个元素不存在
return error;
*e = p->data;
return ok;
}
Status ListInsert(LinkList *L, int i, ElemType e) //插入元素
//需要传递的L一起改变,传递地址
{
int j = 1; LinkList s, p = *L;
//查找的功能部分
while (p && j < i) /* 寻找第i个结点 */
{
p = p->next;
++j;
}
if (!p || j > i)
return error; /* 第i个元素不存在 */
// 插入 代替的部分
//s = (LinkList)malloc(sizeof(Node)); /* 生成新结点(C语言标准函数) */
s = new Node;
s->data = e;
s->next = p->next; /* 将p的后继结点赋值给s的后继 */
p->next = s; /* 将s赋值给p的后继 */
return ok;
}
Status ListDelete(LinkList *L,int i, ElemType *e) //删除元素
{//返回删除的值
int j = 1; LinkList s, p = *L;
//查找的功能部分
while (p && j < i) /* 寻找第i个结点 */
{
p = p->next; //第一个数据
++j;
}
if (!p || j > i)
return error; /* 第i个元素不存在 */
s = p->next; // p->next 这边才是第i的数据
p->next = s->next;
*e = s->data;
delete s;
return ok;
}
Status ClearList(LinkList *L)
{
LinkList s, q;//s为释放的点
s = (*L)->next; /* p指向第一个结点 */
while (s) /* 没到表尾 */
{
q = s->next;
free(s); //指向下一个
s = q;
}
(*L)->next = NULL; /* 头结点指针域为空 */
return ok;
}
#pragma endregion
#pragma region 头插和尾插
void CreateListHead(LinkList *L, int n)
{
LinkList p;
int i;
srand(time(0)); /* 初始化随机数种子 */
//*L = (LinkList)malloc(sizeof(Node));
*L = new Node;
(*L)->next = NULL; /* 先建立一个带头结点的单链表 */
for (i = 0; i<n; i++)
{
//p = (LinkList)malloc(sizeof(Node)); /* 生成新结点 */
p = new Node;
p->data = rand() % 100 + 1; /* 随机生成100以内的数字 */
p->next = (*L)->next; //把前一个头结点数据给p的下一个节点
//实现循环,一直添加在p的后面
(*L)->next = p; //永远是头结点 /* 插入到表头 */
}
}
void CreateListTail(LinkList *L, int n)
{
LinkList p, r;
int i;
srand(time(0)); /* 初始化随机数种子 */
//*L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
*L = new Node;
r = *L; /* r为指向尾部的结点 */
for (i = 0; i<n; i++)
{
//p = (Node *)malloc(sizeof(Node)); /* 生成新结点 */
p = new Node;
p->data = rand() % 100 + 1; /* 随机生成100以内的数字 */
r->next = p; /* 将表尾终端结点的指针指向新结点 */
r = p; /* 将当前的新结点定义为表尾终端结点 */
//这段也是想了好久才想通,
/*
我的理解是 r是指向尾端的节点,
当r->next=p时,由于增加了一个元素导致r不在 尾部
r->next=p是为L服务的
这时候r=p,就是把尾部地址给它,r->next就可以继续循环
*/
}
r->next = NULL; /* 表示当前链表结束 */
}
#pragma endregion
//主函数 ,都有返回值,if 不判断成功与否,可以不用返回值
// 头指针不附带数据,
int main()
{
LinkList L; ElemType e; //链表
ListInit(&L);
cout << "初始化后链表的长度"<< ListLength(L)<<endl;
for (int i = 1; i <= 5; i++)
ListInsert(&L, 1, i);
cout << "插入元素之后";
ListOutput(L);
cout << "测试头指针是否有数据" << L->data << endl;
ListDelete(&L, 3, &e);
cout << "删除的元素是" << e << endl;
ClearList(&L);
cout << "清空数据之后的长度为" <<ListLength(L)<< endl;
CreateListHead(&L,6);
cout << "头插法的数据为";
ListOutput(L);
ClearList(&L);
cout << "清空数据之后的长度为" << ListLength(L) << endl;
CreateListTail(&L, 5);
cout << "尾插法的数据为";
ListOutput(L);
getchar();
return 0;
}
循环链表
typedef struct DulNode
{
ElemType data;//存储数据的
struct DulNode *prior;//指向前驱指针
struct DulNode *next;//指向后继的指针
}DulNode,*DuLinkList;
//删除
p->prior->next=p->next;
p->next->prior=p->prior;