初始化单链表
使用C语言结构体描述该单链表的基础结构
typedef double elementType;
typedef struct LNode {
elementType data;
struct LNode *next;
} LNode, *linkedList;
初始化一个带头结点的单链表
bool InitList_Head(linkedList *L) {
*L = (LNode *) malloc(sizeof(LNode));
if (*L == nullptr) {
return false;
}
(*L)->next = nullptr;
return true;
}
计算从某个结点p开始直到链表末尾的结点总数(包括此结点p)
int listLength(LNode *p) {
if (p == nullptr) {
return 0;
}
int number = 0;
while (p != nullptr) {
number++;
p = p->next;
}
return number;
}
从某个结点P开始,打印N个结点的数据(如果只剩余M个,不够N个,则打印到末尾,即打印M个)
bool listPrint_linkedList(LNode *p, int i) {
if (p == nullptr) {
return false;
}
LNode *q = p;
for (int j = 0; j < i; j++) {
q = q->next;
if (q == nullptr) {
break;
}
std::cout << q->data << " ";
}
std::cout << endl;
return true;
}
单链表插入
在指定节点p之后插入指定数据元素
bool listInsert_nextNode_newElement(LNode *p, elementType element) {
if (p == nullptr) {
return false;
}
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == nullptr) {
return false;
}
s->data = element;
s->next = p->next;
p->next = s;
return true;
}
在指定节点p之后插入指定节点s
bool listInsert_nextNode_newLNode(LNode *p, LNode *s) {
if (p == nullptr || s == nullptr) {
return false;
}
s->next = p->next;
p->next = s;
return true;
}
在指定的链表的索引位置插入指定的数据元素(带头结点链表)
bool listInsert_nextNode_Index_head(linkedList *L, int i, elementType element) {
if (i < 1) {
return false;
}
LNode *p;
int j = 0;
p = *L;
while (p != nullptr && j < i - 1) {
p = p->next;
j++;
}
return listInsert_nextNode_newElement(p, element);
}
在指定的链表结点p之前插入指定的新元素
bool listInsert_priorNode_newElement(LNode *p, elementType element) {
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == nullptr) {
return false;
}
s->data = p->data;
s->next = p->next;
p->next = s;
p->data = element;
return true;
}
在指定的链表结点p之前插入指定的新结点s
bool listInsert_priorNode_newLNode(LNode *p, LNode *s) {
if (p == nullptr || s == nullptr) {
return false;
}
s->next = p->next;
p->next = s;
elementType temp = s->data;
s->data = p->data;
p->data = temp;
return true;
}
单链表删除
删除结点P后面链接的第一个结点(p->next)
bool listDelete_nextLNode_newElement(LNode *p, elementType *deletedElement) {
if (p == nullptr || p->next == nullptr) {
return false;
}
LNode *s = p->next;
*deletedElement = s->data;
p->next = s->next;
free(s);
return true;
}
删除链表的某个索引位置的结点
bool listDelete_elementIndex_head(linkedList *L, int i, elementType *deletedElement) {
if (i < 1) {
return false;
}
LNode *p = *L;
int j = 0;
while (p != nullptr && j < i - 1) {
p = p->next;
j++;
}
return listDelete_nextLNode_newElement(p, deletedElement);
}
删除指定结点P(P不是末尾结点时 O(1) )
bool listDelete_LNode(LNode *p) {
if (p == nullptr) {
return false;
}
if (p->next == nullptr) {
return false;
}
LNode *s = p->next;
p->data = p->next->data;
p->next = s->next;
free(s);
return true;
}
删除指定结点P(先循环找到P的前驱结点,再删除P O(n) )
bool listDelete_LNode_new(linkedList *L, LNode *p) {
if (*L == nullptr || p == nullptr) {
return false;
}
LNode *q = (*L);
while (q->next != p) {
q = q->next;
}
q->next = p->next;
free(p);
return true;
}
尾插法和头插法建立单链表
尾插法
linkedList InitList_end(linkedList *L){
elementType x = 0;
LNode *p = *L;
std::cin >> x;
while(x != -10000){
LNode* s = (LNode*) malloc(sizeof(LNode));
s->data = x;
p->next = s;
p = p->next;
std::cin >> x;
}
p->next = nullptr;
return *L;
}
头插法
linkedList InitList_first(linkedList *L){
elementType x = 0;
LNode *p = *L;
LNode *q = p->next;
std::cin >> x;
while(x != -10000){
LNode *s = (LNode* ) malloc(sizeof(LNode));
s->data = x;
s->next = q;
p->next = s;
q = p->next;
std::cin >> x;
}
return *L;
}
测试函数:test
void test() {
linkedList L2;
InitList_Head(&L2);
LNode *p;
p = L2;
std::cout << "被填入链表的数据时:\n";
for (int j = 1; j <= 5; j++) {
LNode *s = (LNode *) malloc(sizeof(LNode));
L2->next = s;
s->data = j;
L2 = L2->next;
std::cout << L2->data << " ";
L2->next = nullptr;
}
LNode *q = L2;
L2 = p;
std::cout << "\n最初整个链表:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
listDelete_LNode_new(&p, q);
std::cout << "删除最后一个链表结点之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
listInsert_nextNode_Index_head(&p, 1, 195779);
std::cout << "在链表第一个位置插入元素195779之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
listInsert_priorNode_newElement(L2->next, 195778);
std::cout << "在链表第一个结点之前(即更新第一个数据结点)插入元素195778之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
LNode *p_2 = p->next->next;
LNode *s = (LNode *) malloc(sizeof(LNode));
s->data = 195780;
listInsert_priorNode_newLNode(p_2, s);
std::cout << "在链表第二个位置“之前”插入节点s之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
LNode *s2 = (LNode *) malloc(sizeof(LNode));
s2->data = 987654;
listInsert_nextNode_newLNode(p_2, s2);
std::cout << "在链表的第二个位置“之前”插入结点s2之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
elementType x[3] = {0};
for (int i = 0; i < 3; i++) {
listDelete_elementIndex_head(&p, 1, &x[i]);
std::cout << "删除第" << i + 1 << "个节点之后的链表:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
}
std::cout << "最初链表的被删除的三个结点的值为:\n";
for (int i = 0; i < 3; i++) {
std::cout << x[i] << " ";
}
std::cout << "\n\n链表的查找:查找索引位置为5的结点的值为:";
std::cout << listGetLNode_index(&p, 5)->data << endl;
std::cout << "现在整个链表:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl;
std::cout << "链表的查找:查找值为195779的结点的下一个结点的值为:";
LNode* test_x1 = listGetLNode_element(&p,195779)->next;
if(test_x1 != nullptr){
std::cout << test_x1->data << endl << endl;
}
std::cout<<"验证头插法建立单链表L3:\n";
linkedList L3;
InitList_Head(&L3);
LNode* p_3 = L3;
InitList_first(&L3);
listPrint_linkedList(L3,10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_3);
std::cout<<"\n验证尾插法建立单链表L4:\n";
linkedList L4;
InitList_Head(&L4);
LNode* p_4 = L4;
InitList_end(&L4);
listPrint_linkedList(L4,10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_4);
}
E:\CODING__ALAN_CF\cmake-build-debug\LinkedList.exe
被填入链表的数据时:
1 2 3 4 5
最初整个链表:
1 2 3 4 5
此时链表结点总数为(包括头结点):6
删除最后一个链表结点之后:
1 2 3 4
此时链表结点总数为(包括头结点):5
在链表第一个位置插入元素195779之后:
195779 1 2 3 4
此时链表结点总数为(包括头结点):6
在链表第一个结点之前(即更新第一个数据结点)插入元素195778之后:
195778 195779 1 2 3 4
此时链表结点总数为(包括头结点):7
在链表第二个位置“之前”插入节点s之后:
195778 195780 195779 1 2 3 4
此时链表结点总数为(包括头结点):8
在链表的第二个位置“之前”插入结点s2之后:
195778 195780 987654 195779 1 2 3 4
此时链表结点总数为(包括头结点):9
删除第1个节点之后的链表:
195780 987654 195779 1 2 3 4
此时链表结点总数为(包括头结点):8
删除第2个节点之后的链表:
987654 195779 1 2 3 4
此时链表结点总数为(包括头结点):7
删除第3个节点之后的链表:
195779 1 2 3 4
此时链表结点总数为(包括头结点):6
最初链表的被删除的三个结点的值为:
195778 195780 987654
链表的查找:查找索引位置为5的结点的值为:4
现在整个链表:
195779 1 2 3 4
此时链表结点总数为(包括头结点):6
链表的查找:查找值为195779的结点的下一个结点的值为:1
验证头插法建立单链表L3:
15 25 30 -10000
30 25 15
此时链表结点总数为(包括头结点):4
验证尾插法建立单链表L4:
15 25 30 -10000
15 25 30
此时链表结点总数为(包括头结点):4
进程已结束,退出代码为 0
.h文件(不太会搞,好像可以只在.h里面放声明,函数定义在外面?弄不太懂,直接把定义都放进.h文件了)
#ifndef CODING__ALAN_CF_SINGLE_LINKEDLIST_H
#define CODING__ALAN_CF_SINGLE_LINKEDLIST_H
typedef double elementType;
typedef struct LNode {
elementType data;
struct LNode *next;
} LNode, *linkedList;
bool InitList_noHead(linkedList *L) {
*L = nullptr;
return true;
}
bool InitList_Head(linkedList *L) {
*L = (LNode *) malloc(sizeof(LNode));
if (*L == nullptr) {
return false;
}
(*L)->next = nullptr;
return true;
}
bool isEmpty_noHead(linkedList L) {
return (L == nullptr);
}
bool isEmpty_Head(linkedList L) {
return (L->next == nullptr);
}
bool listInsert_nextNode_newElement(LNode *p, elementType element) {
if (p == nullptr) {
return false;
}
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == nullptr) {
return false;
}
s->data = element;
s->next = p->next;
p->next = s;
return true;
}
bool listInsert_nextNode_newLNode(LNode *p, LNode *s) {
if (p == nullptr || s == nullptr) {
return false;
}
s->next = p->next;
p->next = s;
return true;
}
bool listInsert_nextNode_Index_head(linkedList *L, int i, elementType element) {
if (i < 1) {
return false;
}
LNode *p;
int j = 0;
p = *L;
while (p != nullptr && j < i - 1) {
p = p->next;
j++;
}
return listInsert_nextNode_newElement(p, element);
}
bool listInsert_nextNode_Index_noHead(linkedList *L, int i, elementType element) {
if (i < 0) {
return false;
}
if (i == 1) {
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == nullptr) {
return false;
}
s->data = element;
s->next = *L;
*L = s;
return true;
}
LNode *p = *L;
int j = 1;
while (p != nullptr && j < i - 1) {
p = p->next;
j++;
}
return listInsert_nextNode_newElement(p, element);
}
bool listInsert_priorNode_newElement_old(linkedList *L, LNode *p, elementType element) {
LNode *s = *L;
while (s != nullptr) {
if (p == s->next) {
break;
}
s = s->next;
}
if (s == nullptr) {
return false;
}
listInsert_nextNode_newElement(s, element);
}
bool listInsert_priorNode_newElement(LNode *p, elementType element) {
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == nullptr) {
return false;
}
s->data = p->data;
s->next = p->next;
p->next = s;
p->data = element;
return true;
}
bool listInsert_priorNode_newLNode(LNode *p, LNode *s) {
if (p == nullptr || s == nullptr) {
return false;
}
s->next = p->next;
p->next = s;
elementType temp = s->data;
s->data = p->data;
p->data = temp;
return true;
}
bool listDelete_nextLNode_newElement(LNode *p, elementType *deletedElement) {
if (p == nullptr || p->next == nullptr) {
return false;
}
LNode *s = p->next;
*deletedElement = s->data;
p->next = s->next;
free(s);
return true;
}
bool listDelete_elementIndex_head(linkedList *L, int i, elementType *deletedElement) {
if (i < 1) {
return false;
}
LNode *p = *L;
int j = 0;
while (p != nullptr && j < i - 1) {
p = p->next;
j++;
}
return listDelete_nextLNode_newElement(p, deletedElement);
}
bool listDelete_LNode(LNode *p) {
if (p == nullptr) {
return false;
}
if (p->next == nullptr) {
return false;
}
LNode *s = p->next;
p->data = p->next->data;
p->next = s->next;
free(s);
return true;
}
bool listDelete_LNode_new(linkedList *L, LNode *p) {
if (*L == nullptr || p == nullptr) {
return false;
}
LNode *q = (*L);
while (q->next != p) {
q = q->next;
}
q->next = p->next;
free(p);
return true;
}
bool listPrint_linkedList(LNode *p, int i) {
if (p == nullptr) {
return false;
}
LNode *q = p;
for (int j = 0; j < i; j++) {
q = q->next;
if (q == nullptr) {
break;
}
std::cout << q->data << " ";
}
std::cout << std::endl;
return true;
}
int listLength(LNode *p) {
if (p == nullptr) {
return 0;
}
int number = 0;
while (p != nullptr) {
number++;
p = p->next;
}
return number;
}
LNode *listGetLNode_index(linkedList *L, int i) {
if (i < 0) {
return nullptr;
}
LNode *p = *L;
int j = 0;
while (p != nullptr && j < i) {
p = p->next;
j++;
}
return p;
}
LNode *listGetLNode_element(linkedList *L, elementType element) {
LNode *p = (*L)->next;
while (p != nullptr && p->data != element) {
p = p->next;
}
return p;
}
linkedList InitList_end(linkedList *L){
elementType x = 0;
LNode *p = *L;
std::cin >> x;
while(x != -10000){
LNode* s = (LNode*) malloc(sizeof(LNode));
s->data = x;
p->next = s;
p = p->next;
std::cin >> x;
}
p->next = nullptr;
return *L;
}
linkedList InitList_first(linkedList *L){
elementType x = 0;
LNode *p = *L;
LNode *q = p->next;
std::cin >> x;
while(x != -10000){
LNode *s = (LNode* ) malloc(sizeof(LNode));
s->data = x;
s->next = q;
p->next = s;
q = p->next;
std::cin >> x;
}
return *L;
}
#endif
.cpp测试文件
#include<bits/stdc++.h>
#include"Single_linkedList.h"
using namespace std;
void test() {
linkedList L2;
InitList_Head(&L2);
LNode *p;
p = L2;
std::cout << "被填入链表的数据时:\n";
for (int j = 1; j <= 5; j++) {
LNode *s = (LNode *) malloc(sizeof(LNode));
L2->next = s;
s->data = j;
L2 = L2->next;
std::cout << L2->data << " ";
L2->next = nullptr;
}
LNode *q = L2;
L2 = p;
std::cout << "\n最初整个链表:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
listDelete_LNode_new(&p, q);
std::cout << "删除最后一个链表结点之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
listInsert_nextNode_Index_head(&p, 1, 195779);
std::cout << "在链表第一个位置插入元素195779之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
listInsert_priorNode_newElement(L2->next, 195778);
std::cout << "在链表第一个结点之前(即更新第一个数据结点)插入元素195778之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
LNode *p_2 = p->next->next;
LNode *s = (LNode *) malloc(sizeof(LNode));
s->data = 195780;
listInsert_priorNode_newLNode(p_2, s);
std::cout << "在链表第二个位置“之前”插入节点s之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
LNode *s2 = (LNode *) malloc(sizeof(LNode));
s2->data = 987654;
listInsert_nextNode_newLNode(p_2, s2);
std::cout << "在链表的第二个位置“之前”插入结点s2之后:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
elementType x[3] = {0};
for (int i = 0; i < 3; i++) {
listDelete_elementIndex_head(&p, 1, &x[i]);
std::cout << "删除第" << i + 1 << "个节点之后的链表:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
}
std::cout << "最初链表的被删除的三个结点的值为:\n";
for (int i = 0; i < 3; i++) {
std::cout << x[i] << " ";
}
std::cout << "\n\n链表的查找:查找索引位置为5的结点的值为:";
std::cout << listGetLNode_index(&p, 5)->data << endl;
std::cout << "现在整个链表:\n";
listPrint_linkedList(p, 10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl;
std::cout << "链表的查找:查找值为195779的结点的下一个结点的值为:";
LNode* test_x1 = listGetLNode_element(&p,195779)->next;
if(test_x1 != nullptr){
std::cout << test_x1->data << endl << endl;
}
std::cout<<"验证头插法建立单链表L3:\n";
linkedList L3;
InitList_Head(&L3);
LNode* p_3 = L3;
InitList_first(&L3);
listPrint_linkedList(L3,10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_3);
std::cout<<"\n验证尾插法建立单链表L4:\n";
linkedList L4;
InitList_Head(&L4);
LNode* p_4 = L4;
InitList_end(&L4);
listPrint_linkedList(L4,10);
std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_4);
}
int main() {
test();
}