承接上篇,本篇介绍单向链表的另外三种简单操作。
目录
1·链表的插入
若要将r指向的数据项插入到p0和p指向的数据项之间 ,则使p0指向的指针部分指向r指向的数据部分,使r指向的指针部分指向p指向的数据部分。
则有操作:
r->next=p;
p0->next=r;
p0=r;
2·链表的删除
在如上链表中,若要删除p所指的数据项,则有如下操作:
p = p->next;//指向下一项
free(p0->next);//删除掉p原先所指的一项
p0->next = p;
下面参考一道完整例题
题目名称:删除单链表重复结点
题目描述:首先根据键盘随机输入,以0结束的若干非零整数建立单链表;然后删除此链表中值重复的结点仅保留一个,且不改变原有结点顺序;最后将删除后链表中各结点值输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符;若是空链表,则输出NULL。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>
struct cell {
int x;
struct cell* next;
};//单链表结构体定义
struct cell* build(void) {
struct cell* head, * tmp, * p;
head = tmp = p = NULL;
int n;
head = (struct cell*)malloc(sizeof(struct cell));
scanf("%d", &head->x);
tmp = head;
tmp->next = NULL;
if (head->x == 0)head = NULL;
else {
do {
p = (struct cell*)malloc(sizeof(struct cell));
scanf("%d", &p->x);
tmp->next = p;
tmp = p;
tmp->next = NULL;
} while (p->x != 0);
}
return head;
}//新建链表并将建好的单链表首地址返回
struct cell* del2one(struct cell* head) {
struct cell* p, * q, * r;
p = head;
while (p != NULL) {
q = p;
while (q->next != NULL) {
if (q->next->x == p->x) {
r = q->next;
q->next = r->next;
}
else {
q = q->next;
}
}
p = p->next;
}//在p遍历的起始,用q先代替p遍历一遍,如果有与p重复的节点,删除该节点;若没有,则继续遍历
return head;
}//删除重复节点只保留一个
void print(struct cell* head) {
struct cell* p;
printf("%d", head->x);
p = head->next;
while (p->x != NULL) {
printf(" %d", p->x);
p = p->next;
}
}
void release(struct cell* head) {
struct cell* p;
while (head != NULL) {
p = head;
head = p->next;
free(p);
}
}
int main(void) {
struct cell* head;
head = build();
head = del2one(head);
if (head != NULL)
print(head);
else
printf("NULL");
release(head);
}
3·链表的交换
若要将p所指的项与q所指的项交换,最简单的方法是把p所指的项与q所指的项中的基本数据部分交换。但如果数据量过大,则会浪费时间。那么,我们通过修改指针来交换单向链表上的两项:
/*第一步交换p->next、q->next*/
g = p->next;
p->next = q->next;
q->next = g;
/*第二步交换p0->next、q0->next*/
p0->next = q;
q0->next = p;
/*第三步为非必要操作,交换指针p、q*/
p = p0->next;
q = q0->next;
下面来看完整的例题:题目名称:排序单链表
题目描述:
首先根据键盘随机输入一行以0结束的若干非零整数建立单链表;
然后递增排序链表;
最后验证输出排序后链表中所有值,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。
若是空链表,则输出NULL。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>
struct cell {
int x;
struct cell* next;
};
struct cell* build(void) {
struct cell* head, * tmp, * tail;
head = tmp = tail = NULL;
int n;
scanf("%d", &n);
if (n == 0)
return NULL;
head = (struct cell*)malloc(sizeof(struct cell));
head->x = n;
head->next = NULL;
tail = head;
while (1)
{
scanf("%d", &n);
if (n == 0)
return head;
tmp = (struct cell*)malloc(sizeof(struct cell));
tmp->x = n;
tmp->next = NULL;
tail->next = tmp;
tail = tail->next;
}
return head;
}
struct cell* sort(struct cell* head) {
struct cell* p, * p0, * r, * r0, * q;
p = p0 = r = r0 = q = NULL;
p = head;
while (p != NULL) {
r = head;
while ((r->x < p->x) && (r != p))
{
r0 = r;
r = r->next;
}
if (r != p) {
q = p;
p0->next = p->next;
p = p0;
if (r == head) {
q->next = head;
head = q;
}
else {
q->next = r;
r0->next = q;
}
}
p0 = p;
p = p->next;
}
return head;
}
void print(struct cell* head) {
struct cell* p = head;
int flag = 0;
while (p != NULL) {
if (flag)
printf(" ");
flag = 1;
printf("%d", p->x);
p = p->next;
}
}
void release(struct cell* head) {
struct cell* p = head, * tmp;
while (p != NULL) {
tmp = p;
p = p->next;
free(tmp);
}
}
int main(void) {
struct cell* head;
head = build();
if (head != NULL)
{
head = sort(head);
print(head);
}
else
printf("NULL");
release(head);
}
至此,单向链表的基本操作介绍完毕,后续将会再做补充。