zoukankan      html  css  js  c++  java
  • 单链表

    //带头结点
    #include <iostream> #include "stdlib.h" using namespace std; struct Node { int data; struct Node* next; }; //初始化 int initList(Node** head) { *head = new Node; //生成一个头结点,将头指针指向这个头结点 (*head)->next = nullptr; //将头结点的指针域置空 return 1; } //判断链表是否为空 int isEmpty(Node* head) { if (head && head->next) //带头结点则判断头结点的指针域,不带头结点则判断首元结点的指针域。两者都表示为head->next return 0; else return 1; } //销毁链表 int destroyList(Node** head) { while (*head) //3.当head指向最后一个节点(虽然指针域head->next为空,但还是有数据,所以不能不管了,还得释放这个节点)时,不能用判断条件while(head->next),head还得往后移,直到head指向空。 { Node* p = *head; //1.先将头结点保存给p *head = (*head)->next; //2.然后将头结点保存下一个节点的地址,不然销毁p后就找不到下一个节点了,因为下一个节点的地址保存在head节点的指针域中 delete p; //5.p来销毁当前结点,head来遍历(保存当前要销毁的结点的下一个结点的地址) } return 1; //4.包括头结点以及其他所有结点都被销毁掉了 } //清空链表 int clearList(Node* head) { if (head == nullptr) return 0; Node* p = head->next; //1.先将p保存首元结点的地址 while (p) { Node* q = p->next; //2.保存当前要销毁的结点的下一个结点的地址 delete p; //3.p来销毁当前结点,q来遍历(保存当前要销毁的结点的下一个结点的地址) p = q; //4.销毁后将p往后移 } head->next = nullptr; //5.将头结点的指针域置空 return 1; //6.清空所有元素节点,保留头结点,并将头结点指针域置空 } //获取链表的长度 int getListLength(Node* head) { if (head == nullptr) return 0; int length = 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。当前p指向首元结点。 while (p) //2.当p指向最后一个节点(虽然指针域p->next为空,但length还没++)时,不能用判断条件while(p->next),p还得往后移,直到p指向空。 { length++; p = p->next; //当p指向最后一个结点时,p->next为空,赋值给p,则p为空了。如果是一个空表,则head->next为空,赋值给p,则直接退出循环。 } return length; } //获取第i个元素 int getValue(Node* head, int index, int& value) { if (head == nullptr) return 0; if (index < 1)return 0; int i = 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 while (p) { i++; if (i == index) { value = p->data; return 1; } p = p->next; } return 0; } //查找值并返回位置 int findListPos(Node* head, int value, int& index) { if (head == nullptr) return 0; int i = 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 while (p) { i++; if (p->data == value) { index = i; return 1; } p = p->next; } return 0; } //查找值并返回这个结点 Node* findList(Node* head, int value) { if (head == nullptr) return 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 while (p) { if (p->data == value) { break; } p = p->next; } return p; } //在第i个结点前插入一个新结点 int insert(Node* head, int index, int value) { if (head == nullptr) return 0; int i = 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 if (p == nullptr) //空表 { Node* node = new Node; //生成一个新结点 node->data = value; node->next = nullptr; head->next = node; return 1; } else { Node* q = head; //2.保存当前结点p的上一个结点的地址(当插入的是第1个结点前时q指向head,而不是空) while (p) { i++; if (i == index) { Node* node = new Node; //3.生成一个新结点 node->data = value; node->next = p; //4.新结点的指针域保存当前要插入的结点p的地址 q->next = node; //5.将新结点的地址保存到当前要插入的结点p的上一个结点的指针域 return 1; } q = p; //6.保存当前结点p的上一个结点的地址 p = p->next; } } return 0; } //向链表后面依次添加新结点 int addList(Node* head, int value) { if (head == nullptr) return 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 if (p == nullptr) //空表 { Node* node = new Node; //生成一个新结点 node->data = value; node->next = nullptr; head->next = node; } else { while (p->next) //当遍历到最后一个结点时p->next为空,则p为最后一个结点 { p = p->next; } Node* node = new Node; //生成一个新结点 node->data = value; node->next = nullptr; p->next = node; } return 1; } //删除第i个结点(方法一) int deleteNode(Node* head, int index) { if (head == nullptr) return 0; if (index < 1)return 0; int i = 0; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 Node* q = head; //2.q保存p上一个结点的地址 while (p) { i++; if (i == index) { q->next = p->next; //3.将当前结点p的前一个结点q的指针域保存p的下一个结点的地址(p->next) delete p; return 1; } q = p; p = p->next; } return 0; } //删除第i个结点(方法二) int deleteNode_(Node* head, int index) { if (head == nullptr) return 0; if (index < 1)return 0; int i = 0; Node* p = head; //注意这里!!! while (p) { if (i == index - 1) //1.首先找到a(i-1)的存储位置p { Node* deleteNode = p->next; //2.改变指针域前先保存要删除的a(i)的地址以便删除 p->next = p->next->next; //3/将要删除的a(i)结点的前一个结点a(i-1)(也就是p)的指针域指向a(i)的下一个结点 delete deleteNode; return 1; } i++; p = p->next; } return 0; } //遍历输出 void showList(Node* head) { if (head == nullptr) return; Node* p = head->next; //1.不能直接通过head来遍历,这样会改变链表,需要通过p来遍历。将p指向首元结点。 while (p) { cout << p->data << " "; p = p->next; } cout << endl; } //头插法建立单链表 int insertFront(Node** head, int value) { if (*head == nullptr) { //生成头结点 *head = new Node; (*head)->data = 0; (*head)->next = nullptr; } //新建一个结点 Node* node = new Node; node->data = value; node->next = (*head)->next; (*head)->next = node; //头插法只插在头结点的后面 return 1; } //尾插法建立单链表 int insertBack(Node** head, int value) { if (*head == nullptr) { //生成头结点 *head = new Node; (*head)->data = 0; (*head)->next = nullptr; } return addList(*head, value); } void main() { Node* head = nullptr; initList(&head); int ret = isEmpty(head); cout << (ret == 1 ? "链表为空" : "链表不为空") << endl; //for (int i = 0; i < 10; i++) // insert(head, i + 1, i); //当i=0时,要插入的位置为1,head为空表,则生成一个新结点,。当i=1时,要插入的位置为2,但表还只有1个结点,则插入失败,后面也是。 //insert(head, 0, 0); //insert(head, 1, 1); //insert(head, 2, 2); for (int i = 0; i < 10; i++) addList(head, i); insert(head, 3, 100); cout << "在第3个结点前插入新结点100" << endl; showList(head); deleteNode(head, 3); cout << "删除第3个结点" << endl; showList(head); deleteNode_(head, 3); cout << "删除第3个结点" << endl; showList(head); for (int i = 99; i < 109; i++) insertFront(&head, i); cout << "头插法插入结点:" << endl; showList(head); ret = isEmpty(head); cout << (ret == 1 ? "链表为空" : "链表不为空") << endl; int length = getListLength(head); cout << "链表的长度:" << length << endl; int value = 0; getValue(head, 3, value); cout << "第3个元素的值为:" << value << endl; Node* p = findList(head, 8); cout << "第8个结点的值为:" << p->data << endl; int index = 0; findListPos(head, 9, index); cout << "值为9的位置:第" << index << "个元素" << endl; clearList(head); cout << "清空列表!" << endl; ret = isEmpty(head); cout << (ret == 1 ? "链表为空" : "链表不为空") << endl; for (int i = 0; i < 10; i++) addList(head, i); showList(head); ret = isEmpty(head); cout << (ret == 1 ? "链表为空" : "链表不为空") << endl; destroyList(&head); cout << "销毁列表!" << endl; ret = isEmpty(head); cout << (ret == 1 ? "链表为空" : "链表不为空") << endl; Node* head_ = nullptr; for (int i = 10; i < 20; i++) insertBack(&head_, i); cout << "尾插法插入结点:" << endl; showList(head_); for (int i = 99; i < 109; i++) insertFront(&head_, i); cout << "头插法插入结点:" << endl; showList(head_); for (int i = 0; i < 9; i++) addList(head_, i); cout << "尾插法插入结点:" << endl; showList(head_); for (int i = 88; i < 99; i++) insertBack(&head_, i); cout << "尾插法插入结点:" << endl; showList(head_); }
  • 相关阅读:
    [saiku] 系统登录成功后查询Cubes
    216. Combination Sum III
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    211. Add and Search Word
    210. Course Schedule II
    分硬币问题
    开始学习Python
  • 原文地址:https://www.cnblogs.com/tingtaishou/p/14943740.html
Copyright © 2011-2022 走看看