链表的初始化
如每个变量有个名称,链表也应该有个名称(代指),每个链表都需要有个头结点去指代该链表,因此链表初始化需要将头结点给定义出来(phead),还有要将临时插入的结点,也就是pnew给定义出来,一定要注意将指针初始化为NULL,不然会变成野指针
STU *head = NULL, *pnew = NULL;
链表的增(分为头插法 尾插法,头插法后续更新)
前言
笔者学习时有个很严重的错误 就是在插入链表 创建新的节点后 总喜欢把创造完的结点给删除 实际上这个结点不应该删除,就应该让他站内存 删了数据就没了
尾插法
首先判断该链表是否为空链表(没有结点,头结点指向空),如果是空链表,那么pnew作为它的头,如果不是空链表,那么通过头结点遍历到尾结点,再让尾结点插入pnew(新的节点)
void insert_by_tail(STU **head, STU *pnew)
{
STU *pmove = *head;
if (*head == NULL)
{
*head = pnew;
pnew->next = NULL;
}
else
{
while (pmove->next)
{
pmove = pmove->next;
}
pmove->next = pnew;
pnew->next = NULL;
}
pnew = NULL;
}
头插法
pnew指向头部,然后头部指针更换为pnew。
void add_by_head(STU **head, STU *pnew)
{
if (*head == NULL)
{
*head = pnew;
pnew->next = NULL;
}
else
{
pnew->next = *head;
*head = pnew;
}
}
按照任意性质插法
用两个指针,一个指针指向满足某一性质节点的后结点,另一个在满足该性质节点的前结点,然后插入,不过要分情况,分满足该性质的结点是否为头结点或者尾结点。
void Add_by_anywhere(L **head, L *pnew)
{
L *pf, *pb;
pf = *head, pb = *head;
if (*head == NULL || pnew->elem < (*head)->elem)
{
pnew->next = *head;
*head = pnew;
return;
}
while (pb != NULL && pb->elem <= pnew->elem)
{
pf = pb;
pb = pb->next;
}
pf->next = pnew;
pnew->next = pb;
pb = NULL, pf = NULL;
return;
}
链表的查
void prt_linkedlist(STU *head)
{
STU *pmove = head;
while (pmove != NULL)
{
cout << pmove->num << pmove->score << pmove->name << endl;
pmove = pmove->next;
}
}
查单一链表只需要知道其头结点,知道头结点后就直接用pmove遍历头结点直到尾结点
链表删
删除单节点
删除单节点需要用指针pb(前指针),pf(后指针)来找到删除节点的前坐标和当前坐标,让前坐标指向当前坐标的next指针,再free(pf)。
void DeleteNum(STU **head, int num) // 删除某一个元素
{
if (*head == NULL)
{
cout << "None" << endl;
return;
}
STU *pb, *pf;
pb = *head, pf = *head;
while (pb->num != num && pb->next != NULL)
{
pf = pb;
pb = pb->next;
}
if (pb->num == num)
{
if (pb == *head)
{
*head = pb->next;
}
else
{
pf->next = pb->next;
}
free(pf);
}
else
{
cout << "none" << endl;
}
}
删除链表
删除链表就是需要遍历一遍链表,遍历到哪删到哪,用两个指针,一个指针在移动(头指针),一个指针指向移动的指针(pmove),该指针在移动指针(头指针)移动后删当前节点。
void DeleteList(STU **head) // 删除所有链表
{
STU *pmove = *head;
while (*head)
{
pmove = *head;
*head = (*head)->next;
free(pmove);
pmove = NULL;
}
}
链表的改
遍历链表找到哪个节点就停下来 改数据
void ChangeNum(STU **head, int num, int k)
{
STU *pmove = *head;
while (pmove->num != num)
{
pmove = pmove->next;
}
pmove->score = k;
return;
}
链表合并(递归)
注意事项1 创建新节点的时候指向new,注意事项2 head->next=merge(p1,p2) 注意事项3 如果要合并成非重合元素的链表 那么需要判断元素是否相等然后再进行移位, 移位后一定要判断链表是否为空 不然会segmantation default
L *merge(L *head1, L *head2)
{
if (head1 == NULL)
return head2;
else
return head1;
L *head = NULL;
if (head1->data == head2->data)
head1 = head1->next;
if (head1 == NULL)
return head2;
if (head1->data > head2->data)
{
head = head2;
head2 = head2->next;
}
else
{
head = head1;
head1 = head1->next;
}
head->next = merge(head1, head2);
return head;
}
单链表的代码
全部代码
#include <iostream>
#define Elemtype int
using namespace std;
typedef struct List
{
Elemtype elem;
struct List *next;
} L;
void DeleteList(STU **head) // 删除所有链表
{
STU *pmove = *head;
while (*head)
{
pmove = *head;
*head = (*head)->next;
free(pmove);
pmove = NULL;
}
}
void add_by_tail(L **head, L *pnew)
{
L *pmove = *head;
if (*head == NULL)
{
*head = pnew;
pnew->next = NULL;
}
else
{
while (pmove->next != NULL)
{
pmove = pmove->next;
}
pmove->next = pnew;
pnew->next = NULL;
pnew = NULL;
}
}
void add_by_head(L **head, L *pnew)
{
if (*head == NULL)
{
*head = pnew;
pnew->next = NULL;
}
else
{
pnew->next = *head;
*head = pnew;
}
}
void delete_by_Elem(L **head, Elemtype x) // 删头结点的时候一定要注意!!!!
{
L *pf, *pb;
pf = *head, pb = *head;
while (pb && pb->elem != x)
{
pf = pb;
pb = pb->next;
}
if (pb == NULL)
{
cout << "None Delete" << endl;
}
else
{
if (pb == *head)
{
*head = pb->next;
free(pb);
pb = NULL;
pf = NULL;
}
else
{
pf->next = pb->next;
free(pb);
pf = NULL;
pb = NULL;
}
}
}
void PrtList(L **head)
{
L *pmove = *head;
cout << endl
<< "----Print----" << endl;
while (pmove)
{
cout << pmove->elem << " ";
pmove = pmove->next;
}
cout << endl;
}
void ChangeList(L **head, Elemtype a, Elemtype b)
{
L *pmove = *head;
while (pmove && pmove->elem != a)
{
pmove = pmove->next;
}
if (pmove == NULL)
{
cout << "None Change" << endl;
}
else
{
pmove->elem = b;
}
}
void Add_by_anywhere(L **head, L *pnew)
{
L *pf, *pb;
pf = *head, pb = *head;
if (*head == NULL || pnew->elem < (*head)->elem)
{
pnew->next = *head;
*head = pnew;
return;
}
while (pb != NULL && pb->elem <= pnew->elem)
{
pf = pb;
pb = pb->next;
}
pf->next = pnew;
pnew->next = pb;
pb = NULL, pf = NULL;
return;
}
int main()
{
int n;
cout << "amount of LinkeList" << endl;
// n = 5;
List *head = NULL, *pnew = NULL;
cin >> n;
while (n--)
{
pnew = (L *)malloc(sizeof(L));
cin >> pnew->elem;
Add_by_anywhere(&head, pnew);
}
PrtList(&head);
delete_by_Elem(&head, 3);
PrtList(&head);
ChangeList(&head, 2, 5);
PrtList(&head);
}
双向链表
增
头插法
头插法的思路是将pnew->next=head,pnew->prev=NULL,再把头节点更新为pnew
void insertAtBeginning(struct DoubleLinkedList *list, int value)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = list->head;
newNode->prev = NULL;
if (list->head != NULL)
{
list->head->prev = newNode;
}
list->head = newNode; // 插到前面
}
尾插法
思路是先遍历到尾部,让pnew->next=NULL,pnew->prev=pmove,pmove->next=pnew
void insertAtEnd(struct DoubleLinkedList *list, int value)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
if (list->head == NULL)
{
newNode->prev = NULL;
list->head = newNode;
return;
}
struct Node *current = list->head;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
删
思路是遍历到要删的结点 结点前的结点指向结点后结点,结点后的结点指向结点前的结点
void deleteNode(struct DoubleLinkedList *list, int value)
{
struct Node *current = list->head;
while (current != NULL && current->data != value)
{
current = current->next;
}
if (current == NULL)
{
printf("Node with value %d not found.\n", value);
return;
}
current->next->prev = current->prev;
current->prev->next = current->next;
free(current);
printf("Node with value %d deleted.\n", value);
}
改
思路是遍历到要改的数据,替换一下即可
void update(struct DoubleLinkedList *list, int old, int newd)
{
struct Node *current = list->head;
while (current != NULL && current->data != old)
{
current = current->next;
}
if (current == NULL)
{
printf("Node with value %d not found.\n", old);
return;
}
current->data = newd;
printf("Node value updated from %d to %d.\n", old, newd);
}
排序
思路和单链表排序一样,采用冒泡排序,快速排序和归并排序后面随缘更
void sort(struct DoubleLinkedList *list)
{
if (list->head == NULL || list->head->next == NULL)
{
return;
}
struct Node *pf = list->head;
struct Node *pb = NULL;
bool isChange = true;
while (isChange && pb != list->head)
{
isChange = false;
for (pf = list->head; pf->next != pb; pf = pf->next)
{
if (pf->data > pf->next->data)
{
swap(pf->data, pf->next->data);
isChange = true;
}
}
pb = pf;
}
}
循环链表的代码
#include <iostream>
#include <algorithm>
using namespace std;
struct Node
{
int data;
struct Node *next;
struct Node *prev;
};
struct DoubleLinkedList
{
struct Node *head;
};
void initList(struct DoubleLinkedList *list)
{
list->head = NULL;
}
// 头插法
void insertAtBeginning(struct DoubleLinkedList *list, int value)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = list->head;
newNode->prev = NULL;
if (list->head != NULL)
{
list->head->prev = newNode;
}
list->head = newNode; // 插到前面
}
void insertAtEnd(struct DoubleLinkedList *list, int value)
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = value;
newNode->next = NULL;
if (list->head == NULL)
{
newNode->prev = NULL;
list->head = newNode;
return;
}
struct Node *current = list->head;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
// 打印链表
void display(struct DoubleLinkedList *list)
{
struct Node *current = list->head;
while (current != NULL)
{
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
void deleteNode(struct DoubleLinkedList *list, int value)
{
struct Node *current = list->head;
while (current != NULL && current->data != value)
{
current = current->next;
}
if (current == NULL)
{
printf("Node with value %d not found.\n", value);
return;
}
current->next->prev = current->prev;
current->prev->next = current->next;
free(current);
printf("Node with value %d deleted.\n", value);
}
void update(struct DoubleLinkedList *list, int old, int newd)
{
struct Node *current = list->head;
while (current != NULL && current->data != old)
{
current = current->next;
}
if (current == NULL)
{
printf("Node with value %d not found.\n", old);
return;
}
current->data = newd;
printf("Node value updated from %d to %d.\n", old, newd);
}
void search(struct DoubleLinkedList *list, int value)
{
struct Node *current = list->head;
while (current != NULL && current->data != value)
{
current = current->next;
}
if (current == NULL)
{
printf("Node with value %d not found.\n", value);
}
else
{
printf("Node with value %d found.\n", value);
}
}
void sort(struct DoubleLinkedList *list)
{
if (list->head == NULL || list->head->next == NULL)
{
return;
}
struct Node *pf = list->head;
struct Node *pb = NULL;
bool isChange = true;
while (isChange && pb != list->head)
{
isChange = false;
for (pf = list->head; pf->next != pb; pf = pf->next)
{
if (pf->data > pf->next->data)
{
swap(pf->data, pf->next->data);
isChange = true;
}
}
pb = pf;
}
}
int main()
{
struct DoubleLinkedList list;
initList(&list);
// 插入元素
insertAtBeginning(&list, 3);
insertAtBeginning(&list, 2);
insertAtEnd(&list, 5);
insertAtEnd(&list, 6);
insertAtEnd(&list, 1);
insertAtEnd(&list, 4);
printf("Original List: ");
display(&list);
// 删除节点
deleteNode(&list, 5);
printf("List after deletion: ");
display(&list);
// 修改节点值
update(&list, 2, 8);
printf("List after update: ");
display(&list);
// 查找节点
search(&list, 8);
search(&list, 10);
// 排序链表
sort(&list);
printf("Sorted List: ");
display(&list);
return 0;
}
循环链表
循环链表增
采用尾插法,切记将循环链表初始化为NULL
void append(CircularLinkedList *list, int data)
{
Node *newNode = addNode(data);
if (list->head == NULL)
{
list->head = newNode;
newNode->next = list->head;
}
else
{
Node *pmove = list->head;
while (pmove->next != list->head)
{
pmove = pmove->next;
}
pmove->next = newNode;
newNode->next = list->head;
}
}
循环链表查
遍历打印的时候用do while循环 保证循环链表正常进入 打出
void printList(CircularLinkedList *list)
{
Node *pmove = list->head;
do
{
cout << pmove->data << " ";
pmove = pmove->next;
} while (pmove != list->head);
cout << endl;
}
代码
#include <iostream>
using namespace std;
typedef struct Node
{
int data;
struct Node *next;
} Node;
typedef struct
{
Node *head;
} CircularLinkedList;
Node *addNode(int data)
{
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void append(CircularLinkedList *list, int data)
{
Node *newNode = addNode(data);
if (list->head == NULL)
{
list->head = newNode;
newNode->next = list->head;
}
else
{
Node *pmove = list->head;
while (pmove->next != list->head)
{
pmove = pmove->next;
}
pmove->next = newNode;
newNode->next = list->head;
}
}
void printList(CircularLinkedList *list)
{
Node *pmove = list->head;
do
{
cout << pmove->data << " ";
pmove = pmove->next;
} while (pmove != list->head);
cout << endl;
}
int main()
{
int x = 5;
CircularLinkedList list;
list.head = NULL;
while (x--)
{
append(&list, x);
}
printList(&list);
}