一、顺序表
1.顺序表的结构体定义:顺序表可使用数组来实现
#define MAXSIZE 20
typedef struct SqList
{
int* data;//注意这里是数组
int length;
}SqList;
2.顺序表的初始化:
初始化顺序表后为顺序表的data域申请内存空间,L可以认为是顺序表的头结点,头结点的data域用来存放链表的长度
#define MAXSIZE 100
#include <stdio.h>
#include <stdlib.h>
typedef struct SqList
{
int* data;//注意这里是数组
int length;
}SqList;
SqList InitSqList()
{
SqList L;
L.data = (int*)malloc(MAXSIZE * sizeof(int));
L.length = 0;
return L;
}
int main()
{
SqList* L=InitSqList();
return 0;
}
3.获取顺序表指定位置元素
注意判断要获取的数据是否在链表范围内
//获取顺序表指定位置的元素
int GetElem(SqList L, int i, int x)
{
if (i<1||i>L.length)
return 0;
else
{
x = L.data[i];
return x;
}
}
4.查找链表中第一个值为x的数据,并获取其数组下标
//查找顺序表中第一个值等于x的元素
void SearchSqList(SqList L, int x)
{
int i = 0;
for (i = 0; i <= L.length; i++)
{
if (L.data[i] == x)
{
printf("表中第一个值为%d的元素下标为%d\n", x, i);
return;
}
}
printf("表中没有值为%d的元素\n", x);
}
5.插入元素
//插入元素
int InsertSqList(SqList L, int i, int x)
{
if (i<0 || i>L.length || L.length == MAXSIZE)
return 0;
for (int j = L.length; j >= i; j--)
{
L.data[j + 1] = L.data[j];
}
L.data[i] = x;
L.length++;
return 1;
}
6.删除元素
//删除元素
int DeleteSqList(SqList L, int i)
{
if (i<0 || i>L.length)
return 0;
for (int j = i; j <= L.length; j++)
{
L.data[j] = L.data[j + 1];
}
L.length--;
return L.data[i];
}
总体代码实现:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
typedef struct SqList
{
int* data;//注意这里是数组
int length;
}SqList;
SqList InitSqList()
{
SqList L;
L.data = (int*)malloc(MAXSIZE * sizeof(int));
L.length = 0;
return L;
}
//获取顺序表指定位置的元素
int GetElem(SqList L, int i, int x)
{
if (i<1||i>L.length)
return 0;
else
{
x = L.data[i];
return x;
}
}
//查找顺序表中第一个值等于x的元素
void SearchSqList(SqList L, int x)
{
int i = 0;
for (i = 0; i <= L.length; i++)
{
if (L.data[i] == x)
{
printf("表中第一个值为%d的元素下标为%d\n", x, i);
return;
}
}
printf("表中没有值为%d的元素\n", x);
}
//以此打印表中数据
void PrintSqList(SqList L)
{
printf("表中数据为:");
for (int i = 0; i < L.length; i++)
{
printf("%d->", L.data[i]);
}
printf("NULL\n");
}
//插入元素
int InsertSqList(SqList L, int i, int x)
{
if (i<0 || i>L.length || L.length == MAXSIZE)
return 0;
for (int j = L.length; j >= i; j--)
{
L.data[j + 1] = L.data[j];
}
L.data[i] = x;
L.length++;
return 1;
}
//删除元素
int DeleteSqList(SqList L, int i)
{
if (i<0 || i>L.length)
return 0;
for (int j = i; j <= L.length; j++)
{
L.data[j] = L.data[j + 1];
}
L.length--;
return L.data[i];
}
int main()
{
SqList L = InitSqList();
printf("请输入顺序表元素个数\n");
int n = 0;
scanf("%d", &n);
printf("请依次输入顺序表元素\n");
for (; L.length < n; L.length++)
{
scanf("%d", &L.data[L.length]);
}
printf("创建成功\n");
PrintSqList(L);
SearchSqList(L, 99);
InsertSqList(L, 1, 99);
PrintSqList(L);
SearchSqList(L, 99);
DeleteSqList(L, 1);
PrintSqList(L);
SearchSqList(L, 99);
return 0;
}
二、单链表
1.单链表的结构体定义及初始化:
#include <stdio.h>
#include <stdlib.h>
//单链表结构体定义:
typedef struct Node
{
int data;
struct Node* next;
}LNode;
//初始化单链表
Node* InitList()
{
LNode* list = (LNode*)malloc(sizeof(LNode));
list->data = 0;
list->next = NULL;
return list;
}
int main()
{
LNode* list=InitList();
return 0;
}
2.单链表的插入
①头插法:
此处需要注意node->next = list->next;不能放在list->next = node;之后,因为list->已经被赋值为node了。不管是头插法还是尾插法一定要注意有几行代码的顺序是不能颠倒的。
插入新结点的基本思想:
初始化一个临时变量并为其申请内存空间->为该变量的data域赋值->根据插入方法来寻找插入位置->插入新结点。
//单链表插入——头插法(默认含头结点)
void HeadInsert(LNode* list, int data)
{
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = data;
node->next = list->next;
list->next = node;
list->data++;//list是头结点,头结点的data域用来记录结点的个数
}
②尾插法:
此处使用while循环来找到链表的最后一个结点,当head->next为空则循环条件不成立,退出循环,此时的head就是链表的最后一个结点
//单链表插入——尾插法(默认含头结点)
void TailInsert(LNode* list, int data)
{
LNode* head = list;
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = data;
node->next = NULL;
while (head->next)
{
head = head->next;
}
head->next = node;
list->data++;
}
3.删除单链表中值为data的结点:
此处需要定义一个临时变量pre来记录删除结点的上一个结点的地址,即是方便删除操作,也是为了避免结点删除后就找不到上一个结点的地址从而无法连接被删除结点的前后结点
//单链表删除结点
void Delete_Node(LNode* list, int data)
{
if (list == NULL)
return 1;
LNode* pre = list;
LNode* current = list->next;
while (current)
{
if (current->data == data)
{
pre->next = current->next;
free(current);
break;//若要删除多个值相同的结点则注释break
}
pre = current;
current = current->next;
}
if (current == NULL)
return 1;
list->data--;
}
4.遍历单链表
//遍历单链表
void PrintList(LNode* list)
{
list = list->next;
while (list)
{
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
总体代码实现:
#include <stdio.h>
#include <stdlib.h>
//单链表结构体定义:
typedef struct Node
{
int data;
struct Node* next;
}LNode;
//初始化单链表
LNode* InitList()
{
LNode* list = (LNode*)malloc(sizeof(LNode));
list->data = 0;
list->next = NULL;
return list;
}
//单链表插入——头插法(默认含头结点)
void HeadInsert(LNode* list, int data)
{
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = data;
node->next = list->next;
list->next = node;
list->data++;//list是头结点,头结点的data域用来记录结点的个数
}
//单链表插入——尾插法(默认含头结点)
void TailInsert(LNode* list, int data)
{
LNode* head = list;
LNode* node = (LNode*)malloc(sizeof(LNode));
node->data = data;
node->next = NULL;
while (head->next)
{
head = head->next;
}
head->next = node;
list->data++;
}
//单链表删除结点
void Delete_Node(LNode* list, int data)
{
if (list == NULL)
return 1;
LNode* pre = list;
LNode* current = list->next;
while (current)
{
if (current->data == data)
{
pre->next = current->next;
free(current);
break;//若要删除多个值相同的结点则注释break
}
pre = current;
current = current->next;
}
if (current == NULL)
return 1;
list->data--;
}
//遍历单链表
void PrintList(LNode* list)
{
list = list->next;
while (list)
{
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int main()
{
LNode* list = InitList();
for(int i=1;i<=5;i++)
HeadInsert(list, i);
for (int j = 6; j <= 10; j++)
TailInsert(list, j);
PrintList(list);
Delete_Node(list, 5);
Delete_Node(list, 10);
Delete_Node(list, 6);
PrintList(list);
return 0;
}