//SingleList.c 文件
#include "SingleList.h"
#include
#include
#include
void singleListInit(Singlelist* sl) {
sl->_head = NULL;
}
Node* creatNode(Type data) {
Node* node = (Node*)malloc(sizeof(Node));
node->_data = data;
node->_next = NULL;
return node;
}
//尾插操作
//思路: 找到最后一个元素,然后将新创造的节点连接在最后的一位即可.
void singleListPushBack(Singlelist* sl, Type data) {
Node* node = creatNode(data);
if (sl->_head == NULL) {
sl->_head = node;
}
else {
Node* last = sl->_head;
//找到最后一个节点
while (last->_next) {
last = last->_next;
}
//执行尾插操作
last->_next = node;
}
}
//尾删操作:
//思路:找到最后一个节点删除,并且修改前驱的指向为NULl;
void singleListPopBack(Singlelist* sl) {
//找到最后一个节点,并且修改被删除节点的前驱节点的指向
if (sl->_head) {
//找到最后一个节点,遍历的过程更新prev
Node* prev = NULL;
Node* Tail = sl->_head;
while (Tail->_next) {
prev = Tail;
Tail = Tail->_next;
}
if (Tail == sl->_head) {
sl->_head = NULL;
}
else {
prev->_next = NULL;
free(Tail);
}
}
}
//头插操作
//思路: 直接修改头部的指向并且插入新的节点
void singleListPushFront(Singlelist* sl, Type data) {
Node* node = creatNode(data); //创造新的节点
if (sl->_head == NULL) {
sl->_head = node; //假如头部为空的话,直接将新的节点放到给头部
}
else {
node->_next = sl->_head; //修改指向
sl->_head = node;
}
}
//头删操作
//思路:
//1.先将原来要释放的元素保留下来2.将下一个节点给头部3.然后在释放保留之前的节点
void singleListPopFront(Singlelist* sl) {
if (sl->_head == NULL) {
return NULL;
}
else {
if (sl->_head) {
Node* cur = sl->_head; // 保留头结点
sl->_head = cur->_next; //将头结点的指向移到头结点的位置
free(cur); //释放之前保留的头结点
}
}
}
//给pos 后面的节点插入元素
//思路:1.pos位置 2.pos的下一个位置 next 3. 新的节点 newNode
void singleListInsertAfter(Node* pos, Type data) {
if (pos == NULL) {
return;
}
else {
Node* newNode = creatNode(data);
//必须要了解 1.pos位置 2.pos的下一个位置 next 3. 新的节点 newNode
Node* next = pos->_next;
newNode->_next = next;
pos->_next = newNode;
}
}
// 删除pos位置后面的节点
//思路: 要有pos next next->_next
void singleListEraseAfter(Node* pos) {
if (pos == NULL) {
return;
}
else {
Node* next = pos->_next;
if (next) {
pos->_next = next->_next;
free(next);
}
}
}
Node* find(Singlelist* sl, Type data) {
Node* cur = sl->_head;
while (cur) {
if (cur->_data == data) {
return cur;
}
cur = cur->_next;
}
return NULL;
}
void singleListPrint(Singlelist* sl) {
Node* cur = sl->_head;
while (cur) {
printf("%d ", cur->_data);
cur = cur->_next;
}
printf("\n");
}
//Singlelist.h文件
//不带头单向不循环链表
#pragma once
typedef int Type;
typedef struct Node{
Type _data;
struct Node* _next;
}Node;
typedef struct Singlelist{
Node* _head;
}Singlelist;
Node* creatNode(Type data);
void singleListInit(Singlelist* sl);
void singleListPushBack(Singlelist* sl, Type data);
void singleListPopBack(Singlelist* sl);
void singleListPushFront(Singlelist* sl, Type data);
void singleListPopFront(Singlelist* sl);
void singleListInsertAfter(Node* pos, Type data);
void singleListEraseAfter(Node* pos);
void singleListPrint(Singlelist* sl);
Node* find(Singlelist* sl, Type date);
//test.c 测试文件\
#include "SingleList.h"
#include
#include
#include
void test1() {
Singlelist sl;
singleListInit(&sl);
singleListPushBack(&sl, 1);
singleListPushBack(&sl, 2);
singleListPushBack(&sl, 3);
singleListPushBack(&sl, 4);
singleListPushBack(&sl, 5);
singleListPushBack(&sl, 6);
singleListPrint(&sl);
singleListPopBack(&sl);
singleListPrint(&sl);
singleListPopBack(&sl);
singleListPrint(&sl);
singleListPopBack(&sl);
singleListPrint(&sl);
singleListPopBack(&sl);
singleListPrint(&sl);
singleListPopBack(&sl);
singleListPrint(&sl);
singleListPopBack(&sl);
singleListPrint(&sl);
}
void test2() {
Singlelist sl;
singleListInit(&sl);
singleListPushFront(&sl, 1);
singleListPushFront(&sl, 2);
singleListPushFront(&sl, 3);
singleListPushFront(&sl, 4);
singleListPushFront(&sl, 5);
singleListPushFront(&sl, 6);
singleListPrint(&sl);
singleListPopFront(&sl);
singleListPrint(&sl);
singleListPopFront(&sl);
singleListPrint(&sl);
singleListPopFront(&sl);
singleListPrint(&sl);
}
void test3() {
Singlelist sl;
singleListInit(&sl);
singleListPushFront(&sl, 1);
singleListPushFront(&sl, 2);
singleListPushFront(&sl, 3);
singleListPushFront(&sl, 4);
singleListPushFront(&sl, 5);
singleListPushFront(&sl, 6);
singleListPrint(&sl);
Node* pos = find(&sl, 5);
printf("找到元素5,给5的后面插入100: ");
singleListInsertAfter(pos, 100);
singleListPrint(&sl);
Node* pos1 = find(&sl, 1); //找到 1 这个元素,在1 的后面插入200
printf("找到元素1,给1的后面插入200: ");
singleListInsertAfter(pos1, 200);
singleListPrint(&sl);
Node* pos3 = find(&sl, 1);
printf("找到元素1,删除1后面的元素: ");
singleListEraseAfter(pos3);
singleListPrint(&sl);
Node* pos4 = find(&sl, 5);
printf("找到元素5,删除5后面的元素: ");
singleListEraseAfter(pos4);
singleListPrint(&sl);
}
int main () {
//test1();
//test2();
test3();
system("color A");
system ("pause");
return 0;
}
test1函数实现尾插和尾删的操作
test2函数实现头插头删操作
test3函数实现在pos之后位置的插入和删除
//List.c文件
#include "List.h"
#include
#include
void listInit(List* lst) {
//构建一个头结点,构成循环结构
lst->_header = creatNode(0);
lst->_header->_next = lst->_header;
lst->_header->_prev = lst->_header;
}
Node* creatNode(Type data) {
Node* node = (Node*)malloc(sizeof(Node));
node->_data = data;
node->_next = NULL;
node->_prev = NULL;
return node;
}
void ListPushBack(List* lst, Type data) {
Node* node = creatNode(data);
Node* last = lst->_header->_prev;
//last node header
last->_next = node;
node->_prev = last; //先连接内部的
node->_next = lst->_header;
lst->_header->_prev = node; //连接外部的线
//ListInsert(lst->_header, data);
}
void ListPopBack(List* lst) {
Node* last, *prev;
//注意: 不能删除header
if (lst->_header->_next == lst->_header) {
//表示一个空链表 ,没有数据可以删除
return;
}
last = lst->_header->_prev;
prev = last->_prev;
prev->_next = lst->_header;
lst->_header->_prev = prev;
free(last);
ListErase(lst->_header->_prev);
}
void ListPushFront(List* lst, Type data) {
// header node front
Node* node = creatNode(data);
Node* front = lst->_header->_next;
node->_next = front;
front->_prev = node;
node->_prev = lst->_header;
lst->_header->_next = node;
//ListInsert(lst->_header->_next, data);
}
void ListPopFront(List* lst) {
/*Node* front, *next;
if (lst->_header == lst->_header->_next) {
return;
}
front = lst->_header->_next;
next = front->_next;
free(front);
lst->_header->_next = next;
next->_prev = lst->_header;*/
ListErase(lst->_header->_next);
}
//给当前位置的前面插入一个data
void ListInsert(Node* pos, Type data) {
Node* prev = pos->_prev;;
Node* node = creatNode(data);
//prev pos node
prev->_next = node;
node->_prev = prev;
node->_next = pos;
pos->_prev = node;
}
//当前位置的前面进行删除
void ListErase(Node* pos) {
Node* prev, *next;
//删除当前位置的节点
//注意hearder 不能进行删除
if (pos->_next == pos) {
//表示空
return;
}
prev = pos->_prev;
next = pos->_next;
free(pos);
prev->_next = next;
next->_prev = prev;
}
void ListPrint(List* lst) {
Node* cur = lst->_header->_next;
while (cur != lst->_header) {
printf("%d ", cur->_data);
cur = cur->_next;
}
printf("\n");
}
//list.h文件
typedef int Type;
typedef struct Node{
Type _data;
struct Node* _next;
struct Node* _prev;
}Node;
typedef struct List{
Node* _header;
}List;
void listInit(List* lst);
Node* creatNode(Type data);
void ListPushBack(List* lst, Type data);
void ListPopBack(List* lst);
void ListPushFront(List* lst, Type data);
void ListPopFront(List* lst);
//给当前节点的下一个位置插入一个data
void ListInsert(Node* pos, Type data);
//当前节点的下一个位置删除
void ListErase(Node* pos);
void ListDestory(List* lst);
void ListPrint(List* lst);
//test.c文件
#include "List.h"
#include
#include
void test1() {
List lst;
listInit(&lst);
ListPushBack(&lst, 1);
ListPushBack(&lst, 2);
ListPushBack(&lst, 3);
ListPushBack(&lst, 4);
ListPushBack(&lst, 5);
ListPushBack(&lst, 6);
ListPrint(&lst);
//
//ListPopBack(&lst);
//ListPrint(&lst);
//ListPopBack(&lst);
//ListPrint(&lst);
//ListPopBack(&lst);
//ListPrint(&lst);
//ListPopBack(&lst);
//ListPrint(&lst);
//ListPopBack(&lst);
//ListPrint(&lst);
//ListPopBack(&lst);
}
void test2() {
List lst;
listInit(&lst);
ListPushFront(&lst, 1);
ListPrint(&lst);
ListPushFront(&lst, 2);
ListPrint(&lst);
ListPushFront(&lst, 3);
ListPrint(&lst);
ListPushFront(&lst, 4);
ListPrint(&lst);
ListPopFront(&lst);
ListPrint(&lst);
ListPopFront(&lst);
ListPrint(&lst);
ListPopFront(&lst);
ListPrint(&lst);
ListPopFront(&lst);
ListPrint(&lst);
}
int main () {
//test1(); //执行尾插尾删的操作
test2();
//test3();
system("color A");
system ("pause");
return 0;
}
1.顺序表
优点: 1>支持随机访问 2>结构实现简单 3>连续结构 4> 尾插 尾删均是O(1)
缺点: 任意位置的插入删除为O(n),有增容代价.
使用场景: 频繁访问场景
2.链表 (双向)
优点: 1>任意位置的插入删除为O(1) 2>没有有增容代价.
缺点: 1>结构实现复杂 2>非连续结构 3>不支持随机访问
使用场景: 频繁插入场景场景