再寫單鏈表(不帶頭單鏈表)

單鏈表

實際中鏈表的結構非常多樣,以下情況組合起來就有8種鏈表結構:

  1. 單向、雙向
  2. 帶頭、不帶頭
  3. 循環、非循環

雖然有這么多的鏈表的結構,但是我們實際中最常用還是兩種結構:
在這里插入圖片描述

  1. 無頭單向非循環鏈表:結構簡單,一般不會單獨用來存數據。實際中更多是作為其他數據結構的子結 構,如哈希桶、圖的鄰接表等等。另外這種結構在學校的考試中出現很多。
  2. 帶頭雙向循環鏈表:結構最復雜,一般用在單獨存儲數據。實際中使用的鏈表數據結構,都是帶頭雙向 循環鏈表。另外這個結構雖然結構復雜,但是使用代碼實現以后會發現結構會帶來很多優勢,實現反而 簡單了

實現不帶頭單鏈表以及相關操作

頭文件

#pragma oncetypedef int SLDateType;//一個結點
typedef struct SLNode{SLDateType value;struct SLNode *next;
}	SListNode;//不帶頭動態鏈表
typedef struct SList{SListNode *first;
}SList;//初始化
void SListInit(SList *list);
//銷毀
void SListDestroy(SList *list);
//增
//頭插
void SListPushFront(SList *list, SLDateType value);
//尾插
void SListPushBack(SList *list, SLDateType value);//刪
//頭刪
void SListPopFront(SList *list);
//尾刪
void SListPopBack(SList *list);//打印
void SListPrint(const SList *list);//改
void SListUpdata(SListNode *node, SLDateType value);//查
//去查找鏈表中遇到的第一個value,如果沒找到,返回NULL
SListNode *SListFind(const SList *list, SLDateType value);//打印
void SListPrint(const SList *list);void SListInsertBefore(SList *list, SListNode *pos, SLDateType value);
// 在pos的后面插入
void SListInsertAfter(SListNode *pos,SLDateType value); 
// 刪除pos位置的節點 
void SListEraseAfter(SListNode *pos); 
void ListRemove();

功能實現

#include"SList.h"
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include<stdio.h>//初始化
void SListInit(SList *list){assert(list != NULL);list->first = NULL;
}//申請新結點
SListNode* BuyNode(SLDateType value){SListNode *node = (SListNode*)malloc(sizeof(SListNode));assert(node);node->value = value;node->next = NULL;return node;
}
//頭插
void SListPushFront(SList *list, SLDateType value){SListNode *node = (SListNode*)malloc(sizeof(SListNode));assert(node);node->value = value;node->next = list->first;list->first = node;
}//頭刪
void SListPopFront(SList *list){assert(list != NULL);       //鏈表存在assert(list->first != NULL);  //鏈表不為空,里面有結點SListNode *old_first = list->first;list->first = list->first->next;free(old_first);
}
//尾插
void SListPushBack(SList *list, SLDateType value){assert(list != NULL);if (list->first == NULL){ //鏈表中沒有結點的情況就跟頭插的情況是一樣的SListPushFront(list, value);return;}//鏈表中有結點的情況SListNode *cur;for (cur = list->first; cur->next != NULL; cur = cur->next);//cur就是最后一個結點SListNode *node = BuyNode(value);cur->next = node;
}//尾刪
void SListPopBack(SList *list){assert(list != NULL);assert(list->first != NULL);//只有一個結點if (list->first->next == NULL){SListPopFront(list);return;}SListNode *cur = list->first;while (cur->next->next != NULL){cur = cur->next;}free(cur->next);cur->next = NULL; 
}//銷毀
void SListDestroy(SList *list){assert(list != NULL);SListNode *cur = list->first;SListNode *next;while (cur!=NULL){next = cur->next;free(cur);cur = cur->next;}list->first = NULL;
}//打印
void SListPrint(const SList *list){for (SListNode *cur = list->first; cur != NULL; cur = cur->next){printf("%d--->", cur->value);}printf("\n");
}//改
void SListUpdata(SListNode *node, SLDateType value){node->value = value;
}//去查找鏈表中遇到的第一個value,如果沒找到,返回NULL
SListNode *SListFind(const SList *list, SLDateType value){for (SListNode *cur = list->first; cur != NULL; cur = cur->next){if (cur->value == value){return cur;}}return NULL;
}//pos 一定是鏈表中有效結點
//向后面插入
void SListInsertAfter(SListNode *pos, SLDateType value){SListNode *node = BuyNode(value); //申請結點node->next = pos->next;pos->next = node;
}// 刪除pos后面位置的節點 
void SListEraseAfter(SListNode *pos){SListNode *next = pos->next;pos->next = next->next;free(next);}//向pos前面插入
void SListInsertBefore(SList *list, SListNode *pos, SLDateType value){SListNode *cur;SListNode *node = BuyNode(value);for (cur = list->first; cur->next != pos; cur = cur->next);node->next = pos;cur->next = node;
}

測試用例

#include"SList.h"
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>void TestList1(){SList list;SListInit(&list);assert(list.first == NULL);/*SListPushFront(&list, 1);SListPushFront(&list, 2);SListPushFront(&list, 3);//3 2 1*/SListPushBack(&list, 11);SListPushBack(&list, 12);SListPushBack(&list, 13);//3 2 1 11 12 13/*SListPopBack(&list);SListPopBack(&list);SListPopBack(&list);*/SListNode *n12 = SListFind(&list, 12);assert(n12 != NULL);SListPrint(&list);SListInsertAfter(n12, 103);SListPrint(&list);SListEraseAfter(n12);SListPrint(&list);SListInsertBefore(&list,n12, 101);SListPrint(&list);printf("大成功\n");
}int main()
{TestList1();system("pause");return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383179.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383179.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383179.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

再寫雙向循環鏈表

#pragma once #include<assert.h> #include<malloc.h> #include<stdio.h> typedef int DLDataType;//定義鏈表結點結構 typedef struct DListNode{DLDataType value;struct DListNode *prev; //指向前一個結點struct DListNode *next; //指向后一個結點 } DL…

鏈表題目--1 刪除鏈表中所有等于val的值

注意事項 要刪除的結點相鄰第一個結點就是要刪除的結點 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){if(headNULL){return NULL;}struct …

鏈表題目--2 求鏈表的中間結點 和 求鏈表中倒數第k個結點

求鏈表的中間結點 思路 一個走兩步&#xff0c;一個走一步。一個走到尾&#xff0c;另外一個就走到了中間 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head…

鏈表題目---3 合并兩個有序單鏈表 和 分割鏈表

合并兩個有序單鏈表 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){if(l1 NULL){return l2;}else if(l2 NULL){return l1;}struc…

鏈表題目---4 刪除鏈表中重復的結點 和 判斷鏈表是否為回文鏈表

刪除鏈表中重復的結點 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} }; */ class Solution { public:ListNode* deleteDuplication(ListNode* pHead){if(pHead NULL){return NULL;}ListNode *prev NULL; //用于刪除的結點, 是…

鏈表題目----5 相交鏈表 和 環形鏈表 和 返回鏈表開始入環的第一個節點

相交鏈表 思路 鏈表交叉不可能是x型因為有可能兩個鏈表不等長&#xff0c;所以我們必須讓他們從同一起跑位置去起跑從同一起跑位置出發&#xff0c;依次比較每個結點的地址是否相同 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct L…

鏈表題目---6 復制帶隨機指針的鏈表

思路 將新結點放在老結點的后面 復制random 將鏈表拆開 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node() {}Node(int _val, Node* _next, Node* _random) {val _val;next _next;random _random;} }; */ class Solution { publi…

括號匹配問題(c和c++版本實現)

括號匹配問題 思路 遇見左括號入棧&#xff0c;遇見一個右括號彈出棧頂元素右括號入棧前如果棧已經為空&#xff0c;則不匹配如果不為空則讀取并彈出&#xff0c;彈出來的元素與右括號做比較&#xff0c;必須匹配&#xff0c;不匹配返回false;如果最后棧里還有元素&#xff0c…

用隊列實現棧 AND 用棧實現隊列

用隊列實現棧 思路 入隊列就是入棧出隊列的時候&#xff0c;就是把前面size-1個隊列中的元素先出&#xff0c;這樣最后一個元素就成隊首元素了&#xff0c;再把出去的元素再次入隊列讀棧頂元素&#xff0c;過程和第二步是一樣的&#xff0c;就是彈出后&#xff0c;再把它入隊列…

最小棧的實現(設計一個支持 push,pop,top 操作,并能在常數時間內檢索到最小元素的棧。)

最小棧的實現 思路 兩個棧&#xff0c;左邊棧接受元素&#xff0c;右邊棧存最小的元素入棧時&#xff0c;先入左邊棧&#xff0c;隨后進行比較&#xff0c;左邊和右邊棧頂元素進行比較&#xff0c;如果新元素小&#xff0c;就把新元素放在右邊的棧頂位置&#xff0c;如果新元素…

再寫循環隊列----c++實現

再寫循環隊列 class MyCircularQueue { public:/** Initialize your data structure here. Set the size of the queue to be k. */MyCircularQueue(int k) {array (int *)malloc(sizeof(int)*k);capacity k;size 0;front 0;rear 0;}/** Insert an element into the circu…

再談二叉樹(二叉樹概念,二叉樹的性質,二叉樹的存儲結構)

樹的概念 樹的概念 樹是一種非線性的數據結構&#xff0c;它是由n&#xff08;n>0&#xff09;個有限結點組成一個具有層次關系的集合。把它叫做樹是因 為它看起來像一棵倒掛的樹&#xff0c;也就是說它是根朝上&#xff0c;而葉朝下的。它具有以下的特點&#xff1a;每個…

二叉樹題目----1 前序中序后序遍歷二叉樹并返回相應的遍歷(不是打印)

前序遍歷 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*//*** Note: The returned array must be malloced, assume caller calls free().*/ int *array; int size;void _preorde…

二叉樹題目----2 檢查兩顆樹是否相同 和 對稱二叉樹的判定

檢查兩顆樹是否相同 思路 根要相等 p->val q->val左子樹相等 isSameTree(p->left,q->left)右子樹也要相等 isSameTree(p->right,q->right) /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* …

二叉樹題目---3 另一個樹的子樹 AND 二叉樹最大深度

另一個樹的子樹 思路 兩個數都遍歷一遍&#xff0c;找到一個根結點相同時&#xff0c;判斷以這個根結點為首的二叉樹是否相等 前序遍歷判斷兩棵樹是否相同對于返回值的處理是難點 bool isSameTree(struct TreeNode *p, struct TreeNode *q) {if(p NULL && q NULL)…

二叉樹題目----4 前序遍歷重構二叉樹 AND 求二叉樹中所有結點的個數

前序遍歷重構二叉樹 思路 整個二叉樹用數組存儲因為先序遍歷它先遍歷根&#xff0c;再遍歷左&#xff0c;左邊沒有跑完是不會去遍歷右邊的&#xff0c;所以遍歷左子樹&#xff0c;就是數組元素每回向后一個&#xff0c;個數-1遍歷右邊時&#xff0c;就是數組起始位置左子樹跑到…

二叉樹的進階操作---(求二叉樹中所有結點個數,求葉子結點個數,求第k層結點個數;在二叉樹中查找某一結點;層序遍歷;判斷是否為完全二叉樹)

typedef struct TreeNode {struct TreeNode *left;struct TreeNode *right;char val; }TreeNode;typedef struct Result{TreeNode * root; //構建的樹的根結點int used; //構建過程中用掉的val個數 } Result;求二叉樹中所有結點個數 void TreeSize(TreeNode *root, int …

c++中的智能指針詳解(RAII, auto_ptr的原理及其改進,unique_ptr的原理,shared_ptr的原理,shared_ptr的缺陷及其改進)

為什么需要智能指針 代碼中途退出&#xff0c;也能保證資源的合理釋放&#xff0c;在c中沒有垃圾回收機制的情況下&#xff0c;智能指針就可以保證我們申請的資源&#xff0c;最后忘記釋放的問題&#xff0c;防止內存泄露&#xff0c;也幫我們減少了一定的負擔&#xff0c;不用…

Job for mariadb.service failed because the control process exited with error code. Se

錯誤&#xff1a;[rootlocalhost ~]# systemctl start mariadb.service Job for mariadb.service failed because the control process exited with error code. See “systemctl status mariadb.service” and “journalctl -xe” for details. 解決辦法&#xff1a; [rootl…

二叉樹題目----5 平衡二叉樹 AND 根據二叉樹創建字符串

平衡二叉樹 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int MAX(int a,int b) {return a > b ? a : b; }//求高度 int getHeight(struct TreeNode *root){if(root NULL){…