一、 顺序表
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
// 设置顺序表最大容量
#define Maxsize 50
// 顺序表的定义
typedef struct
{
// 顺序表数据
int data[Maxsize];
// 顺序表长度
int length;
} Sqlist;
// 初始化顺序表
bool InitList(Sqlist &L)
{
// 初始化该顺序表长度为0
L.length = 0;
// 返回初始化状态
return true;
}
// 判断顺序表是否为空
bool ListEmpty(Sqlist &L)
{
if (L.length == 0)
return true;
else
return false;
}
// 求表长,即元素个数
void ListLength(Sqlist &L)
{
cout << "当前表中元素个数为:" << L.length << endl;
}
// 在L的第i个位置(位序)插入值为e的数据元素
bool ListInsert(Sqlist &L, int i, int e)
{
// 判断i的合法性
if (i < 1 || i > L.length + 1)
return false;
// 判断表是否已满
if (L.length >= Maxsize) // 判断表是否已满
return false;
// 把从第i个位置开始及之后的元素向后移动一位
for (int j = L.length; j >= i; j--)
{
L.data[j] = L.data[j - 1];
}
// 给第i个位置插入(修改为)新元素
L.data[i - 1] = e;
// 更新顺序表长度
L.length++;
return true;
}
// 打印列表
void PrintL(Sqlist &L)
{
cout << "表中当前的数据是:";
for (int i = 0; i < L.length; i++)
cout << L.data[i] << " ";
cout << endl;
}
// 用e返回第i个元素的值
void GetElem(Sqlist L, int i)
{
cout << "当前表中第" << i << "个位置的元素值为:" << L.data[i - 1] << endl;
}
// 删除第i个位置的数据元素,并用e返回
bool ListDelete(Sqlist &L, int i, int &e)
{
// 判断i的合法性
if (i < 1 || i > L.length)
return false;
// 判断链表是否为空
if (L.length == 0)
return false;
// 获取第i个位置的数据元素
e = L.data[i - 1];
// 把从第i个位置后面的元素向前移动一位
for (int j = i; j < L.length; j++)
L.data[j - 1] = L.data[j];
// 更新顺序表长度
L.length--;
return true;
}
// 返回第一个与e相等的元素的位序(查找值为e的元素的位序)
int LocateElem(Sqlist &L, int e)
{
for (int i = 0; i < L.length; i++)
{
if (L.data[i] == e)
return i + 1;
}
return false;
}
int main()
{
// 新建顺序表L
Sqlist L;
// 初始化顺序表
cout << "初始化结果是:" << InitList(L) << endl;
// 判断顺序表是否为空
cout << "判空结果是:" << ListEmpty(L) << endl;
cout << endl;
cout << "----------" << endl;
cout << endl;
// 在线性表的第1个位置插入9
cout << "在线性表的第1个位置插入9" << endl;
ListInsert(L, 1, 9);
ListLength(L);
PrintL(L);
cout << endl;
// 依次插入(10, 14](批量插入规律的数字)
cout << "尾插入 (10, 14]:" << endl;
int e = 10;
for (int i = 2; i < 6; i++)
{
ListInsert(L, i, e);
e++;
}
ListLength(L);
PrintL(L); // 9 10 11 12 13
cout << endl;
// 插入随机数据
cout << "插入随机数据:" << endl;
ListInsert(L, 3, 66);
ListInsert(L, 6, -88);
ListInsert(L, 2, -3);
ListInsert(L, 5, 24);
ListLength(L);
PrintL(L); // 9 -3 10 66 24 11 12 -88 13 至此,插入完成
cout << endl;
cout << "----------" << endl;
cout << endl;
// 查找指定位序的元素
GetElem(L, 8);
cout << endl;
// 指定位置删除元素
int x;
ListDelete(L, 4, x);
cout << "删除第4个元素!!!" << endl;
cout << "删除的值为:" << x << endl;
PrintL(L);
cout << endl;
// 查找指定元素位序
cout << "查找值为12的元素位序!!!" << endl;
cout << "值为12的元素位序为:" << LocateElem(L, 12) << endl;
return 0;
}
二、单链表
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <typeinfo>
using namespace std;
// 单链表存储定义-写法1
typedef struct LNode
{
int data; // 数据域
struct LNode *next; // 指针域:指向LNode的指针
} LNode, *LinkList;
/*
//单链表存储定义-写法2
struct LNode{
int data;//数据域
struct LNode* next;//指针域:指向LNode的指针
};
typedef struct LNode LNode;
typedef struct LNode* LinkList;//指向LNode的指针
*/
/*
*LinkList其实就是定义了一个名为LinkList的指向struct LNode结构体类型变量的指针,
把它看成struct LNode* LinkList会更加直观。
有了它,我们就可以方便的定义一个单链表L,
本质上和next一样,都是指向结点的指针,这个理解很关键。
*/
// 头插法插入结点
LinkList List_HeadInsert(LinkList &L)
{
LNode *s; // 定义指向插入结点的指针、接收插入数据的变量
int x;
L = (LinkList)malloc(sizeof(LNode)); // 创建头结点
L->next = NULL; // 初始化为空表
cin >> x; // 输入结点数据
while (x != 10000)
{
s = (LNode *)malloc(sizeof(LNode)); // 分配堆区空间
s->data = x; // 设置结点数据
s->next = L->next; // 改链操作
L->next = s;
cin >> x;
}
return L; // 返回链表头结点
}
// 尾插法插入结点
LinkList List_TailInsert(LinkList &L)
{
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode *s;
LNode *r = L; // 表尾指针指向L
L->next = NULL;
cin >> x;
while (x != 9999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
s->next = NULL;
r->next = s;
r = s;
cin >> x;
}
r->next = NULL;
return L;
}
// 头插入结点
bool List_PushFront(LinkList &L);
// 尾插入结点
bool List_PushBack(LinkList &L);
// 头删除结点
bool List_PopFront(LinkList &L);
// 尾删除结点
bool List_PopBack(LinkList &L);
// 释放链表
void List_Destory(LinkList &L)
{
// 记录当前结点
LNode *prev = NULL;
L = L->next;
while (L)
{
// 记录当前结点
prev = L;
// 让头结点指针后移
L = L->next;
// 释放记录结点
free(prev);
}
}
// 获取链表长度
int ListLength(LinkList &L)
{
LNode *p;
int j = 0; // 链表长度
p = L->next; // 跳过头结点
while (p) // 遍历链表
{
p = p->next;
j++;
}
return j;
}
// 查询指定位置的节点
LNode *GetElem(LinkList L, int i)
{
int j = 1;
LNode *p = L->next;
if (i == 0)
return L;
if (i < 1)
return NULL;
while (p && j < i)
{
p = p->next;
j++;
}
return p;
}
// 顺序打印当前表中的数据
void Print(LinkList L)
{
LNode *p;
p = L->next;
cout << "当前表中的数据为:" << endl;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
}
int main()
{
LinkList L1, L2; // 定义名为L1、L2的单链表
cout << "头插法插入结点,请输入数据:(输入10000结束)" << endl;
List_HeadInsert(L1);
cout << "L1当前的表长为:" << ListLength(L1) << endl;
Print(L1);
cout << endl;
cout << endl;
cout << "尾插法插入结点,请输入数据:(输入9999结束)" << endl;
List_TailInsert(L2);
cout << "L2当前的表长为:" << ListLength(L2) << endl;
Print(L2);
cout << endl;
cout << endl;
cout << "表L1的第2个结点的值为:" << GetElem(L1, 2)->data << endl;
cout << "表L2的第4个结点的值为:" << GetElem(L2, 4)->data << endl;
cout << endl;
cout << endl;
cout << "删除单链表L1" << endl;
List_Destory(L1);
cout << endl;
return 0;
}
ps:世界再广,你不闯荡,永远是个旁人;舞台再大,你不上台,永远是个观众;代码再好,你不编写,永远是个看客。动手试试吧!