list.h
#ifndef LIST_H #define LIST_H #include <iostream> #include <stdio.h> #include <malloc.h> //定义单链表结点 typedef struct _node { int data; //数据 struct _node *next; //指向下一结点 }node,*pNode; //创建链表 node *create_list(); //从链表头后插入数据 int insert_listHead(pNode head,int data); //从链表尾后插入数据 int insert_listTail(pNode head, int data); //遍历链表,并显示每个结点的数据 int show_listData(pNode head); //求链表中的结点个数 (不包括链表头,指真正存放数据的结点数目) int getNodeNum(pNode head); //根据索引查找结点,找到返回所找结点 index=0,对应头结点(不存放数据) index=1,对应第一个数据结点 pNode find_nodeByIndex(pNode head,int index); //根据数据查找第一个符合结点(后面也可能有结点的数据为所找数据),找到返回所找结点 pNode find_nodeByData(pNode head,int data); //指定位置插入结点数据 int insert_dataInPos(pNode head,int data,int index); //从链表中删除第index个结点 index范围为1-nodeNum int delete_listIndex(pNode head,int index); //删除整个链表 int delete_listAll(node **head); //根据索引查找结点,找到修改其值 int modify_nodeByIndex(pNode head,int index,int data); //将链表排序 ==0,升序 ==1,降序 int sort_list(pNode head,int sortType); #endif // LIST_H
list.c
#include "list.h" /*************单链表测试程序************/ //创建链表 node *create_list() { pNode head = (pNode)malloc(sizeof(node)); if(!head) { printf("malloc error!\n"); // exit(-1); //在iostream中定义 return NULL; } head->data = 0; head->next = NULL; //不用指向head,由于不是循环链表且是单链表的尾结点的next腰指向NULL return head; } //从链表头后插入结点数据 int insert_listHead(pNode head,int data) { //检测链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } pNode tmpNode = (pNode)malloc(sizeof(node)); //存放插入数据的结点 if(!tmpNode) { printf("malloc error!\n"); return -1; } //将插入数据存入要插入链表的结点 tmpNode->data = data; //将tmpNode插入链表头后 tmpNode->next = head->next; head->next = tmpNode; return 0; } //从链表尾后插入结点数据 int insert_listTail(pNode head, int data) { //检测链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } pNode tmpNode = (pNode)malloc(sizeof(node)); //存放插入数据的结点 if(!tmpNode) { printf("malloc error!\n"); return -1; } //将插入数据存入要插入链表的结点 tmpNode->data = data; //将tmpNode插入链表尾后 tmpNode->next = NULL; //插入链表插入链表尾后,成为新的尾结点,next要指向NULL pNode cur = head; //找到链表尾结点 while(cur->next) //尾结点的next指向NULL,跳出时的cur即为尾结点 { cur = cur->next; } cur->next = tmpNode; //原先尾结点的next指向插入结点 return 0; } //遍历链表,并显示每个结点的数据 int show_listData(pNode head) { //检测链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } //检测链表是否为空 (“为空”与“不存在”不同,为空说明只有一个结点,刚创建还未插入任何结点) if(!head->next) { printf("list isnot exist!\n"); return -1; } pNode cur = head->next; //头结点数据域不保存插入数据,第二个结点才是第一个插入结点 while(cur) { printf("%d ",cur->data); cur = cur->next; } printf("\n"); return 0; } //求链表中的结点个数 (不包括链表头,指真正存放数据的结点数目) int getNodeNum(pNode head) { int nodeNum = 0; //结点数目 //判断链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } //------ //判断链表是否为空 if(!head->next) { printf("list is NULL!\n"); return -1; } pNode cur = head->next; while(cur) { nodeNum++; cur = cur->next; } return nodeNum; } //根据索引查找结点,找到返回所找结点 index=0,对应头结点(不存放数据) index=1,对应第一个数据结点 pNode find_nodeByIndex(pNode head,int index) { //判断链表是否存在 if(!head) { printf("list isnot exist!\n"); return NULL; } //------ //判断链表是否为空 if(!head->next) { printf("list is NULL!\n"); return NULL; } //------ int nodeNum = getNodeNum(head); if(index<=0 || index > nodeNum) //索引必须在允许范围 (1-nodeNum) { printf("pos out of range!\n"); return NULL; } int i = 0; pNode cur = head; while(cur) { i++; cur = cur->next; if(i==index) return cur; } return NULL; //不返回,有警告 } //根据数据查找第一个符合结点(后面也可能有结点的数据为所找数据),找到返回所找结点 pNode find_nodeByData(pNode head,int data) { //判断链表是否存在 if(!head) { printf("list isnot exist!\n"); return NULL; } //------ //判断链表是否为空 if(!head->next) { printf("list is NULL!\n"); return NULL; } pNode cur = head->next; while(cur) { if(cur->data == data) return cur; cur = cur->next; } return NULL; } //指定位置插入结点数据 int insert_dataInPos(pNode head,int data,int index) { //判断链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } //------ //判断链表是否为空 if(!head->next) { printf("list is NULL!\n"); return -1; } //------ int nodeNum = getNodeNum(head); if(index<=0 || index > nodeNum) //指定插入位置必须在允许范围 { printf("pos out of range!\n"); return -1; } //由于find_nodeByIndex的参数2范围限制为1-nodeNum,所以index在那里不能为1,要>=2 if(index==1) //插入到位置1,相当于插入头结点后面 { insert_listHead(head,data); } else //index范围为2-nodeNum { pNode tmpNode = (pNode)malloc(sizeof(node)); if(!tmpNode) { printf("malloc error!\n"); return -1; } tmpNode->data = data; //获得插入位置的前一个结点-insertFrontNode(新数据结点插入到该结点后面) pNode insertFrontNode = find_nodeByIndex(head,index-1); if(!insertFrontNode) //未找到要被插入的结点 { printf("no find insertFrontNode!\n"); return -1; } //若index=2,相当于新数据结点插入到原数据结点1后面,所以需要找到原数据结点1 tmpNode->next = insertFrontNode->next; insertFrontNode->next = tmpNode; } return 0; } //从链表中删除第index个结点 index范围为2-nodeNum int delete_listIndex(pNode head,int index) { //判断链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } //------ //判断链表是否为空 if(!head->next) { printf("list is NULL!\n"); return -1; } //------ int nodeNum = getNodeNum(head); if(index<=1 || index > nodeNum) //index必须在允许范围 { printf("pos out of range!\n"); return -1; } pNode front = find_nodeByIndex(head,index-1); //找到要删除结点的前一个结点 if(!front) { printf("no find!\n"); return -1; } //--------- pNode cur = find_nodeByIndex(head,index); //找到要删除结点 if(!cur) { printf("no find!\n"); return -1; } //删除该结点 front->next = cur->next; free(cur); cur = NULL; return 0; } //删除整个链表 int delete_listAll(node **head) { if(*head == NULL) { printf("list isnot exist!\n"); return -1; } node *cur = (*head)->next; while(cur) { node *tmp = cur; //在free(tmp);后面,那时cur==tmp已经被释放,cur = cur->next不能正常执行了 cur = cur->next; free(tmp); tmp = NULL; } free(*head); (*head) = NULL; return 0; } //根据索引查找结点,找到修改其值 int modify_nodeByIndex(pNode head,int index,int data) { pNode modifyNode = find_nodeByIndex(head,index); //找到要修改的结点 modifyNode->data = data; return 0; //不返回,有警告 } //将链表排序 ==0,升序 ==1,降序 int sort_list(pNode head,int sortType) { //判断链表是否存在 if(!head) { printf("list isnot exist!\n"); return -1; } //------ //判断链表是否为空 if(!head->next) { printf("list is NULL!\n"); return -1; } int nodeNum = getNodeNum(head); int i,j; for(i = 0; i < nodeNum - 1; i++) //冒泡排序法 { for(j = 0; j < nodeNum - 1 - i; j++) { //第一次获取0,1结点 第二次获取1,0结点 node *t_first = find_nodeByIndex(head,j+1); node *t_second = find_nodeByIndex(head,j+2); if(sortType == 0) //升序 { if(t_first->data > t_second->data) { //交换2个结点的值 int tmp = t_first->data; t_first->data = t_second->data; t_second->data = tmp; } } else if(sortType == 1) //降序 { if(t_first->data < t_second->data) { int tmp = t_first->data; t_first->data = t_second->data; t_second->data = tmp; } } else { printf("parame error!\n"); return -1; } } } return 0; }
main.c
#include <iostream> #include <stdio.h> #include <malloc.h> #include "list.h" using namespace std; pNode tmpNode; int main(void) { //创建链表 tmpNode = create_list(); if(!tmpNode) { printf("malloc error!\n"); return -1; } //插入1,3,5,7,9到链表中 for(int i=0;i<10;i++) { insert_listHead(tmpNode,++i); } //插入结点数据 insert_dataInPos(tmpNode,12,2); //获取结点数目 printf("nodeNum=%d\n",getNodeNum(tmpNode)); //遍历显示结点数据 printf("showList: "); show_listData(tmpNode); //根据索引,返回第3个数据结点 index范围为1-nodeNum pNode t_node = find_nodeByIndex(tmpNode,3); if(!t_node) //有可能未找到,则返回NULL,那执行t_node->data会造成程序崩溃 printf("no find!\n"); else printf("t_data:data=%d\n",t_node->data); //返回数据为1的结点 pNode t_node1 = find_nodeByData(tmpNode,1); if(!t_node1) printf("no find!\n"); else printf("t_data:data=%d\n",t_node1->data); //从链表中删除第1个结点 index范围为2-nodeNum delete_listIndex(tmpNode,2); printf("showList: "); show_listData(tmpNode); //升序后显示结点数据 sort_list(tmpNode,0); printf("sortUp showList: "); show_listData(tmpNode); //降序后显示结点数据 sort_list(tmpNode,1); printf("sortUp showList: "); show_listData(tmpNode); //删除所有结点 delete_listAll(&tmpNode); printf("showList: "); show_listData(tmpNode); }
结果运行图: