单链表是一种线性结构,单链表存储分成两部分,一部分存储数据,另一部分存储下一个节点(也就是指向下一个链表的地址(单指向))的地址。
创建头节点,指针域置空。—代码注释为详细内容
//结构体定义链表 typedef struct _LinkNode { int data; //数据域(存储数据) struct _LinkNode* next; //指针节点,指向(存储)下个链表节点的地址 }LinkNode,LinkList; 链表节点、链表 //初始化链表,定义头节点 bool InitList(LinkList* &L) { //构造一个空的单链表 L L = new LinkNode; //创建新结点作为头结点,用头指针L指向头结点 if (!L) { cout << "初始化链表失败!" << endl; return false;//生成结点失败 } L->next = NULL; //头结点的指针域置空 cout << "初始化链表成功!" << endl; return true; }头节点后为每次插入的新节点,先插后出(最先插入的节点的节点元素,输出时则在最后面)
//前插法 bool ListInsert_front(LinkList*& L, LinkNode* node) {//L为头节点,node为新节点(子节点) if (!L || !node) return false;//防止链表为空 node->next = L->next;//将头节点指向的下一个节点的地址赋值给新节点 L->next = node; //将头节点指针指向新节点的地址 return true; }循环找出最后一个节点,然后在该位置插入,原最后节点指针指向新节点,新节点指针设置为空。
//尾插法 bool ListInsert_back(LinkList*& L, LinkNode* node) { LinkNode* last = NULL; if (!L || !node) return false;//判断是否为空 last = L;//指向头链表,将头链表的地址赋给last指针 //通过循环找到最后一个(节点)链表,即指针域存储为NULL的链表 while (last->next) last = last->next;//如果链表中next指针不为空,那么就指向下一个链表的地址 node->next = NULL;//将新节点的指针域设置为空 last->next = node;//将原链表中最后一个节点的指针指向新链表的地址 return true; }通过循环找出要插入位置的节点,然后将(要插入位置的)前节点指针指向新节点的地址,再将新节点指针指向(i+1)的节点的地址。
//任意位置插入 bool LinkInsert(LinkList*& L, int i, int& e) { //在单链表L中,在第i个位置插入元素e if (!L) return false; //判断是否为空 int j = 0; LinkList* p, * s; p = L; //指针p指向头节点 //找出要插入节点位置的前一个结点 while (p && j < i - 1) {//查找位置为i-1的节点,p指向该节点 p = p->next; j++; } if (!p || j > i - 1) {//判断p是否为空或者i值是否合法 return false; } s = new LinkNode;//生成新节点 s->data = e;//把插入的元素值赋值给新结点的数据域 s->next = p->next;//将新节点指针指向原i节点的地址 p->next = s;//将原(i-1)节点指针指向新节点地址 return true; }通过要查找的位置i循环查找链表,找到后把元素值赋值给e。
//单链表的取值 bool Link_GetElem(LinkList* &L,int i,int &e) { //在带头结点的单链表L中查找第i个元素(i为查找的元素位置) //用e记录L中第i个数据元素的值(e为被查找的元素值) int index; LinkList* p; if (!L || !L->next) return false; //判断是否为空 p = L->next;//p指向第一个节点 index = 1; //计数器,记录当前为哪一个节点(链表) while (p && index<i) {//链表依次向后扫描,直到指针p指向所指i个元素或者p为空 p = p->next; //p指向下一个节点(下一个链表的地址) index++; //每循环一次index加1 } if (!p || index > i) { return false; //要查询的元素个数i不合法,i>n或i<=0 } e = p->data;//将被查找节点的元素赋值给e return true; }循环判断该节点元素值是否与要查找元素值相等。
//单链表查找元素(查询) bool Link_FindElem(LinkList* L, int e, int &index) {//按值查找 //在带头结点的单链表L中查找值为e的元素 LinkList* p; p = L->next; //指针p指向第一个节点 index = 1; //计数器 if (!L || !L->next) { index = -1; return false; }//判断是否为空 while (p && p->data != e) { //判断该节点元素值是否与要查找元素值相等 p = p->next; index++; //该节点位置 } if (!p) { index = -1; return false;//查无此值 } return true; }被删除节点要释放内存空间
//单链表中元素的删除 bool LinkDelete(LinkList*& L, int i) {//i为要删除节点的位置 LinkList* p,*q; int index = 0; p = L;//将指针p指向头节点(链表) if (!L || !L->next) { return false; }//判断是否为空 //判断p指针是否为空 要删除节点位置i是否合法 while ((p->next) && (index < i - 1)) {//循环查找i节点 p = p->next; index++; } if (!p->next || (index > i - 1)) {//当i>n或者i<1时,删除位置不合理 return false; } q = p->next; //临时保存被删除节点的地址以备释放空间 p->next = q->next; //将(被删除节点)的前节点的指针指向(被删除节点)的后节点的地址 delete q; //释放被删除节点的空间 return true; }通过循环释放内存空间,完成销毁。
//单链表的销毁 void LinkDestroy(LinkList*& L) { //定义临时节点p指向头节点 LinkList* p = L; //将指针p指向头节点(链表) cout << "销毁链表" << endl; while (p) { L = L->next;//L指向下一个节点 delete p; //删除当前节点 p = L; //p移向下一个节点 } }