自实现链表的相关操作

来源:互联网 发布:elton john知乎 编辑:程序博客网 时间:2024/05/20 05:10

自实现链表的相关操作

#include "stdafx.h"#include <stdlib.h>#include <time.h>typedef struct node{int data;struct node *next;}Node;//创建一个空链表Node* createList(){Node* head = (Node*)malloc(sizeof(Node));head->next = NULL;return head;}//头插法插入节点void headInsert(Node* head, int insertNumber){Node* cur = (Node*)malloc(sizeof(Node));cur->data = insertNumber;cur->next = head->next;head->next = cur;}//尾插法插入节点void tailInsert(Node* head, int insertNumber){static Node* pt = head;//为了保证pt不断变化//main中的for循环会重复调用此函数,而不是一次插入所有节点//所以需要一个在函数结束后也存在的指针一直指向链表的尾节点Node* cur = (Node*)malloc(sizeof(Node));cur->data = insertNumber;pt->next = cur;cur->next = NULL;pt = pt->next;//pt=cur;}//遍历链表void traverseList(Node* head){head = head->next;//越过头节点while (head != NULL){printf("%d\n", head->data);head = head->next;}}//求链表的长度int lenList(Node* head){int len = 0;head = head->next;while (head != NULL){len++;head = head->next;}return len;}//查找节点(返回此节点的地址)Node* searchList(Node* head,int findData){head = head->next;while (head != NULL){if (findData == head->data){return head;}head = head->next;}return NULL;}//删除节点(主要查找所要删除节点的前一个节点的地址)void deleteList(Node* head, Node* pfind){while (head->next != pfind) head = head->next;//得到前趋节点head->next = pfind->next;//将所删节点俩边连接上free(pfind);//释放所删节点}//链表的冒泡排序(值的交换)void sortPopList_Value(Node* head, int len)//长度len相当于冒泡排序中的个数{Node* cur = head;//head的替身int tmp;for (int i = 0; i < len - 1; i++)//控制趟数{//每次大循环都是将cur指向头节点的下一个节点,并从cur开始往后进行比较(冒泡)cur = head->next;for (int j = 0; j < len - 1 - i; j++)//控制次数(不再推动比较){if (cur->data > cur->next->data)//头指针的后俩个节点进行比较{tmp = cur->data;cur->data = cur->next->data;cur->next->data = tmp;}cur = cur->next;//作为推动比较的条件,cur往后进一步,cur->next固然也相当于往后走一步}}}//链表的冒泡排序(指针的交换)void sortPopList_Point(Node* head, int len){Node* sh = NULL;//头指针的替身Node* p = NULL;//第一个比较节点Node* q = NULL;//第二个比较节点Node* tmp = NULL;//储存地址的容器for (int i = 0; i < len - 1; i++){sh = head;p = sh->next;q = p->next;for (int j = 0; j < len - 1 - i; j++){if (p->data > q->data)//前一个节点值大于后一个节点值{//交换俩个节点sh->next = q;p->next = q->next;q->next = p;//俩个节点交换后p、q位置发生改变,需要交换p、q地址的位置//因为需要符合 if中的判断条件 pq必须进行交换tmp = q;q = p;p = tmp;}//不管是否发生交换三个值都需要往后走推动循环sh = sh->next;p = p->next;q = q->next;}}}//链表的反转void reverseList(Node* head){Node* p;Node* q;p = head->next;//p指向头节点的下一个节点head->next = NULL;//先打断链表,将链表一分为二while (p != NULL)//判断待插入的节点是否为空{q = p->next;//保存p的下一个节点//进行头插p->next = head->next;head->next = p;p = q;//将保存的节点重新赋值给p进行下一次判断,p的位置不能变动}}int _tmain(int argc, _TCHAR* argv[]){srand(time(NULL));Node *head = createList();for (int i=0; i < 10; i++){//tailInsert(head, i);//headInsert(head, rand()%100);headInsert(head, i);}//traverseList(head);//reverseList(head);//printf("after reverseList:\n");//traverseList(head);headInsert(head, 20);//确保有data为20的节点int len = lenList(head);printf("链表长=%d\n", len);traverseList(head);printf("========================================\n");Node* pfind = searchList(head, 20);if (NULL == pfind){printf("find none\n");}else{printf("所查节点在链表中,地址为: %p\n",pfind);//已经查询到所要节点deleteList(head, pfind);traverseList(head);len = lenList(head);//sortPopList_Value(head, len);sortPopList_Point(head, len);printf("冒泡排序后:\n");traverseList(head);}return 0;}