单链表
建立链表结点的结构体有关链表问题,我折腾了好长时间,总是断断续续的。如果想统一花一点时间攻克,估计也差不多能攻克了,折腾来折腾去,拖延症一犯,到现在也没有完全弄清楚。现在先把自己搞明白的有关链表的内容搞明白。
说起单链表,有以下几个方面的内容需要你会写。
- 建立单链表。
要想实现对链表的操作,首先的当然是建立链表啦。没有链表怎么进行插入删除查找操作啊。
建立单链表有以下几个部分
- 建立链表结点的结构体。
- 为结点分配空间
- 为结点赋值
- 为结点确定位置
以下是建立的链表结点的结构体
1 typedef struct Node 2 { 3 int element; 4 struct Node *next; 5 }node;其次是创建链表的函数了:
/******************************** *描述:创建链表 *参数:无 *返回值:链表头指针 *******************************/ node *creat() { node *head, *p, *q; int x = 0; bool cycle = true; head = (node*)malloc(sizeof(node)); p = head; while (cycle) { printf("请输入一个整数"); scanf("%d", &x); if (x != 0) { q = (node*)malloc(sizeof(node)); q->element = x; p->next = q; p = q; } else cycle = false; } head = head->next; p->next = NULL; return head; }创建链表时候尤为注意几点:1:为结点分配空间。2:为结点赋值3:为结点确定位置。
node *head; head = creat();
在主函数当中,用这两句,就能轻松调用创建链表的函数进行使用了。
还有几个小函数,不是很关键,但是学学还是很有用的,没准什么时候就能用到,看下面。
/******************************** *描述:测量链表长度 *参数:head:链表头指针 *返回值:链表长度 *******************************/ int flength(node *head) { int count = 1; node *p; p = head; while (p->next != NULL) { ++count; p = p->next; } return count; } /******************************** *描述:打印链表 *参数:head:链表头指针 *返回值:链表长度 *******************************/ void fprint(node *head) { int length = flength(head); node *pdata = head; for (int i = 0; i < length; ++i) { printf("第%d个元素的值为%d", i, pdata->element); pdata = pdata->next; } }
2.删除元素
删除元素中涉及到一些技巧,注意一下。
/******************************** *描述:删除链表中的某个元素 *参数:head:链表头指针 * num:要删除的数据 *返回值:链表头 *******************************/ node *fdelete(node *head, int num) { node *p1, *p2; p1 = head; p2 = head; while (num != p1->element&&p1->next != NULL) { p2 = p1; p1 = p1->next; } if (num == p1->element)//删除的元素是头结点还是非头结点要分别对待。 { if (p1 == head) { head = p1->next; free(p1); } else { p2->next = p1->next; free(p1); p1 = NULL;// 写这句的目的是不能让p1成为悬空指针。 } } else printf("找不到要删除的元素!!!"); }
搜寻整个链表,找寻某个值是否存在于链表之中
/******************************** *描述:查询某元素 *参数:head:链表头 * num:要查询的数据 *返回值:无 *******************************/ void fsearch(node *head, int num) { node *p1; p1 = head; while (p1->element != num&&p1->next != NULL) { p1 = p1->next;//找寻下面一个链表结点是否符合条件 } if (p1->element == num) { printf("%d值已经找到了",num); } else { printf("搜遍整个链表,此值不存在"); } }
插入一个链表的操作,现在看来已经非常简单了。
/******************************** *描述:插入一个数,插入数据的原则为从小到大 *参数:head:链表头 * num:插入的数据 *返回值:链表头 *******************************/ node* finsert(node *head, int num ) { node *p0,*p1, *p2; p1 = p2 = head;//给予指针初始位置 p0->element = num; while (p0->element >= p1->element) { p1 = p1->next; p2->next = p1; } if (p1 == head) { p0->next = p1; head = p0; } else if (p1->next != NULL) { p2->next = p0; p0->next = p1; } else { p1->next = p0; p0->next = NULL; } return head; }
用链表实现冒泡排序和一般数组的冒泡排序没什么差别
/******************************** *描述:链表冒泡排序,从大到小 *参数:head:链表头 *返回值:无 *******************************/ void fsort(node *head) { node *q; int len = flength(head); for (int i = 0; i < len; ++i) { for (q = head; q->next != NULL; q = q->next) { if (q->element < q->next->element) { int temp; temp = q->element; q->element = q->next->element; q->element = temp; } } } }
用链表实现逆序排序
/******************************** *描述:链表逆置 *参数:head:表头 *返回值:node:返回新的链表头 *******************************/ node *freverse(node *head) { node *p0=NULL,*p1=NULL,*p2=NULL; if(flength(head)<=1){ printf("\n链表节点至少为2"); return NULL; } else{ p1=head; p2=p1->next; while(p2!=NULL){ //一定要用p2判断,否则错误 p0=p2->next; p2->next=p1; p1=p2; p2=p0; } head->next=NULL; head=p1; printf("\n链表逆置完成"); return head; } }