顺序表、链表、双向循环链表
SeqList.h
#pragma once
#include<stdio.h>
#define ListSize 100 //线性表的最大长度
typedef int DataType;
typedef struct
{
DataType data[ListSize]; //用数组存储线性表中的元素
DataType length; //顺序表的长度
}SeqList, *PSeqList;
void InitList(PSeqList L); //顺序表的初始化操作
int LengthList(PSeqList L); //求顺序表的长度
int GetData(PSeqList L, int i); //返回数据表中第i个元素的值
int InsList(PSeqList L, int i, DataType e); //在顺序表的第i个位置插入元素
int DelList(PSeqList L, DataType i, DataType* e); //删除顺序表L的第i个数据元素
int Locate(PSeqList L, DataType e); //查找数据元素e在表中的位置
void PushFront(PSeqList L, DataType e); //头插,在表头插入元素e
void PopFront(PSeqList L); //头删,删除表中的第一个元素
void PushBack(PSeqList L, DataType e); //尾插,在表尾插入元素e
void PopBack(PSeqList L); //尾删,删除表尾元素
void ClearList(PSeqList L); //清空顺序表
int EmptyList(PSeqList L); //判断顺序表是否为空
void PrintList(PSeqList L); //打印表中元素
SeqList.c
#include "SeqList.h"
int k = 0; //全局变量,用于作部分操作的循环变量
//初始化顺序表
void InitList(PSeqList L)
{
if (L == NULL)
{
return;
}
L->length = 0;
}
//求顺序表的长度
int LengthList(PSeqList L)
{
if (L == NULL)
{
return 0;
}
return L->length;
}
//返回数据表中第i个元素的值
int GetData(PSeqList L, int i)
{
if (L->length < 1 || (L->length > LengthList(L)))
{
return 0;
}
//数据元素的序号从1开始,数组下表从0开始,第i个元素对应的数组下标为i-1;
return L->data[i - 1];
}
//在L中第i个位置,插入新的数据元素e
int InsList(PSeqList L, int i, DataType e)
{
//判断插入位置是否合法
if (i < 1 || L->length >(LengthList(L) + 1))
{
printf("插入位置不合法!\n");
return 0;
}
//判断顺序表是否已满
else if (L->length >= ListSize)
{
printf("顺序表已满,不能插入!\n");
return 0;
}
else
{
for (k = L->length; k >i; k--)
{
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e;
L->length++; //数据表的长度加1
return 1;
}
return 0;
}
//删除L的第i个数据元素
int DelList(PSeqList L, DataType i, DataType* e)
{
if (L->length < 1)
{
printf("表为空!\n");
return 0;
}
*e = L->data[i - 1];
for (k = i; k < L->length; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
return *e;
}
//查找e在表中的位置
int Locate(PSeqList L, DataType e)
{
for (k = 0; k < L->length; k++)
{
if (L->data[k] == e)
{
//k为e对应的数组下标,在表中对应序号应为k+1
return k + 1;
}
}
return 0;
}
//头插,在表头插入元素e
void PushFront(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("顺序表已满,不能插入!\n");
}
//将表中元素依次后移一位
for (k = L->length; k > 0; k--)
{
L->data[k] = L->data[k - 1];
}
//插入元素
L->data[0] = e;
L->length++;
}
//头删,删除顺序表中的第一个元素,把顺序表中的元素依次往前移动一位
void PopFront(PSeqList L)
{
if (EmptyList(L))
{
printf("顺序表为空,不能插入!\n");
}
for (k = 1; k <= L->length - 1; k++)
{
L->data[k - 1] = L->data[k];
}
L->length--;
}
//尾插
void PushBack(PSeqList L, DataType e)
{
if (L->length == ListSize)
{
printf("顺序表已满,不能插入!\n");
}
L->data[L->length] = e;
L->length++;
}
//尾删
void PopBack(PSeqList L)
{
if (EmptyList(L))
{
printf("表为空!\n");
}
L->length--;
}
//清空顺序表
void ClearList(PSeqList L)
{
L->length = 0;
}
//判断表是否为空
int EmptyList(PSeqList L)
{
if (L->length == 0)
{
return 1;
}
return 0;
}
//打印表中元素
void PrintList(PSeqList L)
{
if (EmptyList(L))
{
printf("表为空!\n");
return;
}
for (k = 0; k < L->length; k++)
{
printf("%-3d", L->data[k]);
}
printf("\n");
}
Dlist.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DLDataType;
typedef struct DListNode
{
DLDataType value;
struct DListNode *prev;
struct DListNode *next;
}DListNode;
typedef struct DList
{
DListNode *head;
}DList;
//初始化
void DListInit(DList *dlist);
//申请节点
static DListNode* DListBuyNode(DLDataType value);
//头插
void DListPushFront(DList *dlist, DLDataType value);
//打印
void DListPrint(DList *dlist);
//尾插
void DListPushBack(DList *dlist, DLDataType value);
//查
DListNode* DListFind(const DList* dlist, DLDataType value);
//在 pos 前面进行插入 value
void DListInsertFront(DListNode* pos, DLDataType value);
//头删
void DListPopFront(DList *dlist);
//尾删
void DListPopBack(DList *dlist);
//删除 pos 位置的结点
void DListErase(DListNode* pos);
//彻底销毁链表
void DListDestroy(DList *dlist);
//按顺序合并有序双链表
void DListMerge(DList *list1, DList *list2);
Dlist.c
#include"Dlist.h"
//申请节点
DListNode* DListBuyNode(DLDataType value)
{
DListNode *node = (DListNode *)malloc(sizeof(DListNode));
node->value = value;
node->next = NULL;
node->prev = NULL;
return node;
}
//初始化
void DListInit(DList *dlist)
{
assert(dlist != NULL);
dlist->head = DListBuyNode(0);
dlist->head->next = dlist->head;
dlist->head->prev = dlist->head;
}
//头插
void DListPushFront(DList *dlist, DLDataType value)
{
assert(dlist != NULL);
DListNode *node = DListBuyNode(value);
node->next = dlist->head->next;
dlist->head->next->prev = node;
dlist->head->next = node;
node->prev = dlist->head;
}
//打印
void DListPrint(DList *dlist)
{
assert(dlist != NULL);
DListNode *cur;
for (cur = dlist->head->next ;cur != dlist->head;cur = cur->next)
{
printf("%d->", cur->value);
}
printf("\n");
}
//尾插
void DListPushBack(DList *dlist, DLDataType value)
{
assert(dlist != NULL);
DListNode *node = DListBuyNode(value);
node->prev = dlist->head->prev ;
node->next = dlist->head;
dlist->head->prev->next = node;
dlist->head->prev = node;
}
//查
DListNode* DListFind(const DList* dlist, DLDataType value)
{
assert(dlist != NULL);
DListNode *cur = dlist->head->next;
while (cur!=dlist->head )
{
if (cur->value == value)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//在 pos 前面进行插入 value
void DListInsertFront(DListNode* pos, DLDataType value)
{
assert(pos != NULL);
DListNode *node = DListBuyNode(value);
node->prev = pos->prev;
node->next = pos;
node->prev->next = node;
pos->prev = node;
}
//头删
void DListPopFront(DList *dlist)
{
assert(dlist != NULL);
DListNode *node = dlist->head->next ;
node->next->prev = dlist->head;
dlist->head->next = node->next;
free(node);
}
//尾删
void DListPopBack(DList *dlist)
{
assert(dlist != NULL);
DListNode *node = dlist->head->prev;
node->prev->next = dlist->head;
dlist->head->prev = node->prev;
}
//删除 pos 位置的结点
void DListErase(DListNode* pos)
{
assert(pos != NULL);
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
free(pos);
}
//彻底销毁链表
void DListDestroy(DList *dlist)
{
assert(dlist != NULL);
DListNode *cur;
DListNode *pre;
cur = dlist->head->next;
while (cur != dlist->head)
{
pre = cur->next;
free(cur);
cur = pre;
}
dlist->head->next = dlist->head->prev = dlist->head;
free(dlist->head);
dlist->head = NULL;
}
//按顺序合并有序双链表
void DListMerge(DList *dlist1, DList *dlist2)
{
DListNode *cur1 = dlist1->head ->next ;
DListNode *cur2 = dlist2->head ->next ;
DListNode *tmp1;
DListNode *tmp2;
while (cur1 !=dlist1->head &&cur2 !=dlist2->head )
{
if (cur1->value > cur2->value)
{
tmp1 = cur1->prev;
tmp2 = cur2->next;
cur1->prev = cur2;
cur2->next = cur1;
tmp1->next = cur2;
cur2->prev = tmp1;
cur2 = tmp2;
}
else
{
cur1 = cur1->next;
}
}
if (cur1 == dlist1->head)
{
tmp2 = dlist2->head ->prev;
cur2->prev = cur1->prev;
cur1->prev->next = cur2;
cur1->prev = tmp2;
tmp2->next = cur1;
}
free(dlist2->head);
}
Slist.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SLNode
{
SLDataType value;
struct SLNode *next;
}SLNode;
typedef struct
{
SLNode *first;
}SList;
//初始化
void SListInit(SList *list);
//创建节点
SLNode *SListBuyNode(SLDataType value);
//头插
void SListPushFront(SList *list, SLDataType value);
//尾插
void SListPushBack(SList *list, SLDataType value);
//打印
void SListPrint(const SList *list);
//在pos后面插入value
void SListInsertAfter(SLNode *pos, SLDataType value);
//去找到链表中遇到的第一个 value,如果没找到,返回NULL
SLNode * SListFind(const SList *list, SLDataType value);
//在pos前面插入value
void SListInsertBefore(SLNode *list, SLNode *pos, SLDataType value);
//头删
void SListPopFront(SList *list);
//尾删
void SListPopBack(SList *list);
//销毁
void SlistDestory(SList *list);
//删除 pos 后面的 value
void SListEraseAfter(SLNode *pos);
//约瑟夫环问题
void YueSheFu(int m, int n);
Slist.c
#include"Slist.h"
//初始化
void SListInit(SList *list)
{
assert(list != NULL);
list->first = NULL;
}
//创建节点
SLNode *SListBuyNode(SLDataType value)
{
SLNode *node = (SLNode*)malloc(sizeof(SLNode));
assert(node != NULL);
node->value = value;
node->next = NULL;
return node;
}
//头插
void SListPushFront(SList *list, SLDataType value)
{
assert(list != NULL);
SLNode *node = SListBuyNode(value);
assert(node != NULL);
node->next = list->first;
list->first = node;
}
//尾插
void SListPushBack(SList *list, SLDataType value)
{
assert(list != NULL);
if (list->first == NULL)
{
SListPushFront(list, value);
return;
}
SLNode *cur = list->first;
while (cur->next)
{
cur = cur->next;
}
SLNode *node = SListBuyNode(value);
cur->next = node;
node->next = NULL;
}
//打印
void SListPrint(const SList *list)
{
assert(list != NULL);
SLNode *cur = list->first;
for (cur = list->first;cur;cur = cur->next)
{
printf("%d->", cur->value);
}
printf("NULL\n");
}
//在pos后面插入value
void SListInsertAfter(SLNode *pos, SLDataType value)
{
assert(pos != NULL);
SLNode *node = SListBuyNode(value);
node->next = pos->next;
pos->next = node;
}
//去找到链表中遇到的第一个 value,如果没找到,返回NULL
SLNode * SListFind(const SList *list, SLDataType value)
{
assert(list != NULL);
SLNode *cur;
for (cur = list->first;cur;cur = cur->next)
{
if (cur->value == value)
{
return cur;
}
}
return NULL;
}
//在pos前面插入value
void SListInsertBefore(SList *list, SLNode *pos, SLDataType value)
{
assert(pos != NULL);
assert(list != NULL);
SLNode *node = SListBuyNode(value);
SLNode *cur = list->first;
while (cur->next != pos)
{
cur = cur->next;
}
cur->next = node;
node->next = pos;
}
//头删
void SListPopFront(SList *list)
{
assert(list != NULL);
assert(list->first != NULL);
SLNode *old_first = list->first;
list->first = list->first->next;
free(old_first);
}
//尾删
void SListPopBack(SList *list)
{
assert(list != NULL);
SLNode *cur = list->first;
while (cur->next->next != NULL)
{
cur = cur->next;
}
free(cur->next);
cur->next = NULL;
}
//销毁
void SlistDestory(SList *list)
{
assert(list != NULL);
SLNode *cur = list->first;
SLNode *right;
while (cur != NULL)
{
right = cur->next;
free(cur);
cur = right;
}
list->first = NULL;
}
//删除 pos 后面的 value
void SListEraseAfter(SLNode *pos)
{
SLNode *next = pos->next;
pos->next = next->next;
free(next);
}
//约瑟夫环问题
void YueSheFu(int m, int n)
{
SLNode *last;
SList *head;
SLNode *cur;
SListInit(&head);
SListPushFront(&head, m);
last = head;
for (int i = m - 1;i >= 1;i--)
{
SListPushFront(&head, i);
}
SListPrint(&head);
last->next = head;
cur = last;
for (;m > 1;m--)
{
for (int i = 1;i < n;i++)
{
cur = cur->next;
printf("%d报%d\n", cur->value, i);
}
printf("%d号出圈\n", cur->next->value);
SListEraseAfter(cur);
}
printf("%d号胜利", cur->value);
}
main.c
#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include"SeqList.h"//顺序表
#include"Slist.h"//无头单向非循环链表
#include"Dlist.h"//带头双向循环链表
void HeBing()
{
DList dlist1;
DList dlist2;
DListInit(&dlist1);
DListInit(&dlist2);
DListPushFront(&dlist1, 9);
DListPushFront(&dlist1, 7);
DListPushFront(&dlist1, 5);
DListPushFront(&dlist1, 3);
DListPushFront(&dlist1, 1);
DListPushFront(&dlist2, 10);
DListPushFront(&dlist2, 8);
DListPushFront(&dlist2, 6);
DListPushFront(&dlist2, 4);
DListPushFront(&dlist2, 2);
DListPrint(&dlist1);//1 3 5 7 9
DListPrint(&dlist2);//2 4 6 8 10
DListMerge(&dlist1, &dlist2);
DListPrint(&dlist1);//1 2 3 4 5 6 7 8 9 10
}
void WFD()
{
SList list;
SListInit(&list);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPushFront(&list, 5);
SListPushBack(&list, 6);
SListPushBack(&list, 7);
SListPushBack(&list, 8);
SListPushBack(&list, 9);
SListPrint(&list);//5 4 3 2 1 6 7 8 9
SLNode *ret = SListFind(&list, 2);
SListInsertAfter(ret, 19);
SListPrint(&list);//5 4 3 2 19 1 6 7 8 9
SListInsertBefore(&list, ret, 99);
SListPrint(&list);//5 4 3 99 2 19 1 6 7 8 9
SListPopFront(&list);
SListPrint(&list);//4 3 99 2 19 1 6 7 8 9
SListPopBack(&list);
SListPrint(&list);//4 3 99 2 19 1 6 7 8
SListEraseAfter(ret);
SListPrint(&list);//4 3 99 2 1 6 7 8
SlistDestory(&list);
}
void YXD()
{
DList dlist;
DListInit(&dlist);
DListPushFront(&dlist, 1);
DListPushFront(&dlist, 2);
DListPushFront(&dlist, 3);
DListPushFront(&dlist, 4);
DListPushFront(&dlist, 5);
DListPushFront(&dlist, 6);
DListPrint(&dlist);
DListPushBack(&dlist, 6);
DListPushBack(&dlist, 7);
DListPushBack(&dlist, 8);
DListPushBack(&dlist, 9);
DListPrint(&dlist);
DListNode *ret = DListFind(&dlist, 1);
DListInsertFront(ret, 99);
DListPrint(&dlist);
DListPopFront(&dlist);
DListPrint(&dlist);
DListPopBack(&dlist);
DListPrint(&dlist);
DListErase(ret);
DListPrint(&dlist);
DListDestroy(&dlist);
}
void YSF()
{
int m = 0;
int n = 0;
printf("请输入m个人,n为数(n<m)");
scanf("%d%d", &m, &n);
YueSheFu(m, n);
}
void SXB()
{
SeqList L;
DataType data;
//初始化顺序表
InitList(&L);
//在表中插入元素
printf("依次在表中插入元素(1,2,3,4,5):\n");
InsList(&L, 1, 1);
InsList(&L, 2, 2);
InsList(&L, 3, 3);
InsList(&L, 4, 4);
InsList(&L, 5, 5);
//打印表中元素
printf("表中元素有:\n");
PrintList(&L);
//头插
printf("在表头依次插入元素,6,7:\n");
PushFront(&L, 6);
PushFront(&L, 7);
//尾插
printf("在表尾依次插入元素,8,9:\n");
PushBack(&L, 8);
PushBack(&L, 9);
printf("表中元素有:\n");
PrintList(&L);
//头删
printf("头删一个元素:\n");
PopFront(&L);
//尾删
printf("尾删一个元素:\n");
PopBack(&L);
//输出表中第4个元素值
PrintList(&L);
printf("表中第4个元素值为:\n%d\n", GetData(&L, 4));
//查找表中第 i个元素的位置
printf("元素2在表中的位置为:\n");
printf("%d\n", Locate(&L, 2));
//删除表中第2个元素对应的值
printf("删除表中第2个元素:%d\n", DelList(&L, 2, &data));
printf("顺序表的长度为:%d\n", LengthList(&L));
printf("表中元素为:\n");
PrintList(&L);
//printf("删除的元素值为:%d\n", data);
//清空顺序表
ClearList(&L);
PrintList(&L);
}
int main()
{
//约瑟夫问题
//YSF();
//按顺序合并有序双链表
//HeBing();
//无头非循环单链表基本操作
//WFD();
//有头循环双链表基本操作
//YSF();
//顺序表
SXB();
system("pause");
return 0;
}