单链表基本操作概括
发布时间:2021-11-19 13:08:23 所属栏目:教程 来源:互联网
导读:链表基本概念: 链表:线性表的链式存储。 数据域:存储数据信息。即数据。 指针域:存放下一节点的位置信息。即该指针指向下一节点。 单链表:每一个节点node:一个数据域 + 一个指针域。 头节点: 1、数据域可以存放线性表长度等公共信息。 2、指针域,指
链表基本概念: 链表:线性表的链式存储。 数据域:存储数据信息。即数据。 指针域:存放下一节点的位置信息。即该指针指向下一节点。 单链表:每一个节点node:一个数据域 + 一个指针域。 头节点: 1、数据域可以存放线性表长度等公共信息。 2、指针域,指向第一个节点(数据域)的位置。 3、头结点不一定是链表的必须元素。不过有了头结点,对第一个元素节点前插入和删除元素,就和其它节点一致了。 4、头结点是为了操作的同一和方便设立的,其数据域一般无意义,也可存放链表长度。 头指针:指向第一个结点的指针。 最后一个节点:数据域存放数据;指针域为空,即NULL。 若线性表为空,则头节点的指针域为空。 // 循环链表:将单链表中的终端节点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表简称循环链表。 // 双向链表:是在单链表的每个节点中,再设置一个指向其前驱节点的指针域。 单链表基本操作有:创建、输出、测长、插入、删除、逆置、排序等。 单链表结构定义代码: typedef struct Node{ int data; struct Node *next; }ListNode; 创建单链表操作: /**创建链表*/ ListNode * Create_list(int n) // 注意这里函数返回值为一个指向Node的指针,n表示几个节点 { int elem,i; i = 1; ListNode *head, *current, *temp; /*current:代表一个当前节点,它的下一节点是你正要创建的;temp:代表你正要创建的节点。*/ head = new ListNode; head->next = NULL; head->data = n; current = head; while(i <= n) /*尾插法:即新节点放在尾部*/ { cout << "please input elem: " << endl; cin >> elem; temp = new ListNode; temp->data = elem; temp->next = NULL; current->next = temp; current = temp; i++; } return head; } 输出操作: /**输出链表*/ int Output_list(ListNode *head) { ListNode *p; p = head->next; if(p == NULL) { cout << "The List is NULL" << endl; return 0; } do{ cout << p->data << ' '; p = p->next; }while(p != NULL); // 这里需要加“;” cout << endl; return 0; } 测一个链表的节点数,即长度: /**测长度*/ int Length_test(ListNode *head) { ListNode *p; int i = 0; p = head->next; while(p != NULL) { i++; p = p->next; } cout << "The length of list is " << i << endl; return 0; } 插入节点操作: /**在第i个节点后插入一个节点,elem:表示你要插入的数据*/ ListNode * Insert_node(ListNode *head,int elem,int i) { int j = 0; ListNode *p,*temp; temp = head->next; /*错误写法 while(NULL != temp) 在找到 j 后没有跳出循环 { j++; if(j <= i) temp = temp->next; } */ while(NULL != temp) { j++; if(j >= i) /**指针停在第i个节点之前*/ break; temp = temp->next; } if(temp == NULL) { cout << "There is no i" << endl; return head; } p = new ListNode; p->data = elem; p->next = temp->next; temp->next = p; head->data = head->data + 1; /**插入一个结点,头结点数据保存的链表长加一*/ return head; } 删除操作: /**删除第i个结点*/ ListNode * Delete_node(ListNode *head,int i) { int j = 0; ListNode *temp,*pre_temp; temp = head->next; while(NULL != temp) { j++; if(j >= i) break; pre_temp = temp; /**保存之前节点*/ temp = temp->next; } if(temp == NULL) { cout << "There is no i" << endl; return head; } pre_temp->next = temp->next; /**这里不能写成temp = temp->next; 因为下面有 delete temp;会将后面的节点删掉*/ delete temp; head->data -= 1; /**删掉一个结点,头结点数据保存的链表长减一*/ return head; } 逆置操作: /**单链表逆置,将头结点后的节点一个个断开,使用头插法插入在头结点后*/ ListNode * Reverse_list(ListNode *head) { if(NULL == head) return head; if(NULL == head->next) return head; if(NULL == head->next->next) return head; /**要实现逆置,除了头结点外,至少需要2个数据节点*/ ListNode *curr, *temp; curr = head->next; /**curr用来保存断开后的那一串*/ head->next = NULL; /**头结点与后面结点断开*/ while(NULL != curr) { temp = curr->next; /**temp起临时代替curr的作用*/ curr->next = head->next; /**头插法*/ head->next = curr; curr = temp; /**temp将功能还给curr*/ } return head; } 单链表排序(使用冒泡排序法):此排序算法,仅交换了数据,没有交换结点 void Swap_data(int &a,int &b) /**这里必须要加引用符,不然交换没效果*/ { int temp; temp = a; a = b; b = temp; } ListNode * Sort_list(ListNode *head) { int i,len; ListNode *p; len = head->data; p = head->next; if(NULL == p) cout << "list is null" << endl; for(i = 1; i <= len; i++) { while(NULL != p->next) { if(p->data > p->next->data) Swap_data(p->data,p->next->data); p = p->next; } p = head->next; } return head; } 一个特别的函数:用于找出单链表中间节点,在不知道节点总数的情况下 /**不知节点总数,只遍历一次就可以求出中间结点*/ /**这个函数有问题,只能对节点为奇数的求解,节点为偶数时,会出现p->next->next无意义的情况,使程序发生错误*/ /*原理是:找两个指针,一个每次走一步,另一个每次走两步,当走两步的指针到结尾时,走一步的指针刚好走到中间结点处*/ void Search_mid(ListNode *head) { ListNode *p_1,*q_2; ListNode *mid; p_1 = head->next; q_2 = head->next; while(NULL != q_2->next) { p_1 = p_1->next; q_2 = q_2->next->next; mid = p_1; } cout << "中间值为: " << mid->data << endl; } 测试主函数: int main() { ListNode *p; int a=3; int b = 4; p = Create_list(5); cout << "The list is:" << endl; Output_list(p); Length_test(p); p = Insert_node(p,6,5); cout << "插入节点后:" << endl; Output_list(p); cout << "New length: " << p->data << endl; p = Delete_node(p,3); cout << "删除节点后:" << endl; Output_list(p); p = Reverse_list(p); cout << "逆置后:" << endl; Output_list(p); p = Sort_list(p); cout << "排序后(从小到大):" << endl; Output_list(p); cout << "原ab: " << a << b << endl; Swap_data(a,b); cout << "交换后: " << a << b << endl; Search_mid(p); return 0; } ![]() (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |