简介
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
本文通过c++代码形式简单的实现了单向链表的增加节点,删除节点,打印链表,和销毁链表操作。
c++示例代码
1 #include <iostream> 2 3 using namespace std; 4 5 //单链表节点 6 struct ListNode { 7 //节点存储的数字 8 int m_nValue; 9 //下一个节点的指针 10 ListNode* m_pNext; 11 }; 12 13 /************************************************************************/ 14 /* @brif 在链表结尾增加节点 15 /* @param pHead 链表头结点 16 /* @param value 要增加的节点值 17 /************************************************************************/ 18 void AddNodeToTail(ListNode** pHead, int value) 19 { 20 ListNode *addNode = new ListNode; 21 22 if (!addNode) 23 { 24 cout << "add node fail!!!" << endl; 25 return; 26 } 27 addNode->m_nValue = value; 28 addNode->m_pNext = nullptr; 29 30 //头结点为空的情况,新增加的节点作为头结点 31 if (!*pHead) 32 { 33 *pHead = addNode; 34 } 35 //头结点不为空的情况,查找到最后一个节点,修改最后一个节点的指向 36 else 37 { 38 ListNode* tmpNode = *pHead; 39 //找到最后一个头结点 40 while (tmpNode->m_pNext) 41 { 42 tmpNode = tmpNode->m_pNext; 43 } 44 tmpNode->m_pNext = addNode; 45 } 46 } 47 48 /************************************************************************/ 49 /* @brif 删除链表中的其中一个节点 50 /* @param pHead 链表头结点 51 /* @param value 要删除的节点值 52 /************************************************************************/ 53 void removeNode(ListNode** pHead, int value) 54 { 55 ListNode* currNode = *pHead; 56 57 cout << "删除节点" << value << endl; 58 if (!currNode) 59 { 60 cout << "空链表" << endl; 61 } 62 63 //删除头结点 64 if (currNode ->m_nValue == value) 65 { 66 *pHead = currNode->m_pNext; 67 delete currNode; 68 return; 69 } 70 71 //查找要删除的节点 72 while (currNode->m_pNext && currNode->m_pNext->m_nValue != value) 73 { 74 currNode = currNode->m_pNext; 75 } 76 77 //找到最后一个都没找到这个节点 78 if (!currNode->m_pNext) 79 { 80 cout << "没找到要删除的节点" << endl; 81 } 82 //找到了要删除的节点,修改节点指针,释放内存 83 else 84 { 85 ListNode* delNode = currNode->m_pNext; 86 currNode->m_pNext = currNode->m_pNext->m_pNext; 87 delete delNode; 88 } 89 } 90 91 /************************************************************************/ 92 /* @brif 删除链表中的所有节点 93 /* @param pHead 链表头结点 94 /************************************************************************/ 95 void removeAllNode(ListNode** pHead) 96 { 97 ListNode* currNode = *pHead; 98 99 if (!*pHead) 100 { 101 cout << "空链表" << endl; 102 } 103 104 ListNode* delNode = nullptr; 105 while ((*pHead)->m_pNext) 106 { 107 delNode = (*pHead); 108 (*pHead) = (*pHead)->m_pNext; 109 delete delNode; 110 delNode = nullptr; 111 } 112 delete (*pHead); 113 *pHead = nullptr; 114 } 115 116 /************************************************************************/ 117 /* @brif 打印链表中的节点 118 /* @param pHead 链表头结点 119 /************************************************************************/ 120 void printLinkList(ListNode* pHead) 121 { 122 ListNode* currNode = pHead; 123 124 if (!currNode) 125 { 126 cout << "空链表" << endl; 127 } 128 129 while (currNode) 130 { 131 cout << currNode->m_nValue << "->"; 132 currNode = currNode->m_pNext; 133 } 134 cout << "结束" << endl; 135 } 136 137 int main() 138 { 139 ListNode* pHead = nullptr; 140 141 cout << "从空连表中依次在尾部插入10个值:" << endl; 142 //空链表中依次插入10个值 143 for (int i = 1; i <= 10; ++i) 144 { 145 AddNodeToTail(&pHead, i); 146 printLinkList(pHead); 147 } 148 149 //删除节点1 150 removeNode(&pHead, 1); 151 printLinkList(pHead); 152 153 //删除节点10 154 removeNode(&pHead, 10); 155 printLinkList(pHead); 156 157 //删除节点5 158 removeNode(&pHead, 5); 159 printLinkList(pHead); 160 161 //删除不存在的节点11 162 removeNode(&pHead, 11); 163 printLinkList(pHead); 164 165 //清理现场释放内存 166 removeAllNode(&pHead); 167 168 cout << endl; 169 return 0; 170 }