#include <stdio.h>
#include <stdlib.h>
#define newNode (LinkedList *)malloc(sizeof(LinkedList)) //快捷生成新结点
typedef struct k
{ //定义单链表
int data;
struct k *next;
} LinkedList;
LinkedList *append()
{ //尾插法,返回一个带头结点的单链表,注意返回的只能是地址
int x;
LinkedList *h, *p; // h是头结点的指针
h = (LinkedList *)malloc(sizeof(LinkedList)); //创建一个结点,即头结点
h->next = NULL; //创建结点后对next初始化
//下面向单链表添加元素
LinkedList *tail;
printf("请输入一组数,以-1结束 \n");
scanf("%d", &x);
tail = h;
while (x != -1)
{
//造新的结点
p = newNode;
//对p的各个域进行初始化赋值
p->data = x;
p->next = NULL;
//将p插入到链表的尾部
tail->next = p;
tail = p;
//继续读入一个x
scanf("%d", &x);
}
return h;
}
LinkedList *append2()
{ //尾插法,返回一个带头指针的单链表,注意返回的只能是地址
int x;
LinkedList *h, *p; // h是头结点的指针
printf("请输入一组数,以-1结束 \n");
scanf("%d", &x);
if (x == -1)
return NULL;
h = (LinkedList *)malloc(sizeof(LinkedList)); //创建一个结点,即头结点
h->next = NULL;
h->data = x;
//下面向单链表添加元素
LinkedList *tail;
tail = h;
scanf("%d", &x);
while (x != -1)
{
//造新的结点
p = newNode;
//对p的各个域进行初始化赋值
p->data = x;
p->next = NULL;
//将p插入到链表的尾部
tail->next = p;
tail = p;
//继续读入一个x
scanf("%d", &x);
}
return h;
}
LinkedList *crea_h()
{ //使用头插法输入带头结点单链表
int x;
LinkedList *h, *p;
h = (LinkedList *)malloc(sizeof(LinkedList));
h->next = NULL;
LinkedList *head;
printf("请输入一组数,以-1结束\n");
scanf("%d", &x);
head = h;
while (x != -1)
{
p = newNode;
p->data = x;
p->next = NULL;
p->next = head->next;
head->next = p;
scanf("%d", &x);
}
return h;
}
void show(LinkedList *h)
{ //打印带头结点的单链表h
LinkedList *p;
for (p = h->next; p != NULL; p = p->next)
printf("%d ", p->data);
printf("\n");
}
void show2(LinkedList *h)
{ //打印头指针单链表h
LinkedList *p;
for (p = h; p != NULL; p = p->next)
printf("%d ", p->data);
printf("\n");
}
void find_del(LinkedList *h, int x)
{ //在头结点单链表中查找x并删除
LinkedList *p, *pre;
for (pre = h, p = h->next; p != NULL && p->data != x; p = p->next, pre = pre->next)
;
// if(p->data=x)//此判断有误,若for循环因p=NULL结束循环,则p->next出现了空指针引用
if (p == NULL)
{
printf("Not found!");
return;
}
//能走到此处,表示已经找到了x
pre->next = p->next;
free(p); // p->data数据需要删除,所以需要释放p指针
}
void find_ina(LinkedList *h, int x, int y)
{ //头结点单链表找到x在x前插入y;
LinkedList *p, *q, *pre;
q = newNode;
q->data = y;
p = h->next;
pre = h;
for (pre = h, p = h->next; p != NULL && p->data != x; p = p->next, pre = pre->next)
;
if (p == NULL)
{
printf("Not found!");
return;
}
q->next = p;
pre->next = q;
}
void find_inb(LinkedList *h, int x, int y)
{ //头结点单链表找到x在x后插入y;
LinkedList *p, *q;
q = newNode;
q->data = y;
q->next = NULL;
for (p = h->next; p != NULL && p->data != x; p = p->next)
;
if (p == NULL)
{
printf("Not found!");
return;
}
q->next = p->next;
p->next = q;
}
void insertSorted(LinkedList *h, int x)
{ //在头结点单链表升序表中插入元素x
LinkedList *p, *q, *pre;
for (pre = h, p = h->next; p->data < x; p = p->next, pre = pre->next)
;
q = newNode;
q->data = x;
q->next = NULL;
q->next = p;
pre->next = q;
}
void findMin(LinkedList *h)
{ //查找头结点单链表h中的最小值并将其与首元素交换
LinkedList *p, *min;
int temp;
if (h->next == NULL)
return; //若为空链表返回;
min = h->next;
if (min->next == NULL)
return; //若链表只有一个元素直接返回;
p = min->next;
while (p != NULL)
{
if (p->data < min->data)
min = p;
p = p->next;
}
p = h->next; //把p改成首元素;也可以直接用h
temp = p->data;
p->data = min->data;
min->data = temp;
}
void findMind(LinkedList *h)
{ //查找头结点单链表h中的最小值,并将其摘除,重新插入到链表的第一个位置
LinkedList *prep, *p, *preMin, *min;
if (h->next == NULL)
return; //若为空链表直接返回;
preMin = h;
min = preMin->next;
prep = h->next;
p = prep->next;
if (min->next == NULL)
return; //若链表只有一个元素直接返回;
while (p != NULL)
{
if (p->data < min->data)
{
preMin = prep;
min = p;
}
p = p->next;
prep = prep->next;
}
preMin->next = min->next;
min->next = h->next;
h->next = min;
}
LinkedList *madeup(LinkedList *h1, LinkedList *h2)
{ //将两个头结点单链表升序表合并成头结点单链表降序表;
LinkedList *p, *q, *t;
LinkedList *h3;
h3 = (LinkedList *)malloc(sizeof(LinkedList)); //创建一个结点,即头结点
h3->next = NULL;
p = h1->next;
q = h2->next;
while (p != NULL && q != NULL)
{
if (p->data < q->data)
{
t = p; //贴标签
p = p->next;
t->next = h3->next;
h3->next = t;
}
else
{
t = q;
q = q->next;
t->next = h3->next;
h3->next = t;
}
}
while (p != NULL)
{
t = p;
p = p->next;
t->next = h3->next;
h3->next = t;
}
while (q != NULL)
{
t = q;
q = q->next;
t->next = h3->next;
h3->next = t;
}
return h3;
}
LinkedList *madeup2(LinkedList *h1, LinkedList *h2)
{ //将两个头指针单链表升序表合并成头指针单链表降序表;
LinkedList *p, *q, *t;
LinkedList *h3;
p = h1;
q = h2;
h3 = newNode;
h3 = NULL;
while (p != NULL && q != NULL)
{
if (p->data < q->data)
{
t = p; //贴标签
p = p->next;
t->next = h3;
h3 = t;
}
else
{
t = q;
q = q->next;
t->next = h3;
h3 = t;
}
}
while (p != NULL)
{
t = p;
p = p->next;
t->next = h3;
h3 = t;
}
while (q != NULL)
{
t = q;
q = q->next;
t->next = h3;
h3 = t;
}
return h3;
}
LinkedList *HeBIng(LinkedList *h1, LinkedList *h2)
{ //头指针降序合成升序
LinkedList *p, *q, *r, *h3;
p = h1;
q = h2;
h3 = newNode;
h3 = NULL;
while (p != NULL && q != NULL)
{
if (p->data < q->data)
{
r = p;
p = p->next;
r->next = h3;
h3 = r;
}
else
{
r = q;
q = q->next;
r->next = h3;
h3 = r;
}
}
while (p != NULL)
{
r = p;
p = p->next;
r->next = h3;
h3 = r;
}
while (q != NULL)
{
r = q;
q = q->next;
r->next = h3;
h3 = r;
}
return h3;
}
void madeup1(LinkedList *h1, LinkedList *h2, LinkedList *h3)
{ //将两个头结点单链表升序表合并成头结点单链表降序表;
LinkedList *p, *q, *t;
p = h1->next;
q = h2->next;
while (p != NULL && q != NULL)
{
if (p->data < q->data)
{
t = p;
p = p->next;
t->next = h3->next;
h3->next = t;
}
else
{
t = q;
q = q->next;
t->next = h3->next;
h3->next = t;
}
}
while (p != NULL)
{
t = p;
p = p->next;
t->next = h3->next;
h3->next = t;
}
while (q != NULL)
{
t = q;
q = q->next;
t->next = h3->next;
h3->next = t;
}
}
void delodd(LinkedList *h)
{ //头结点链表删除h中的所有奇数;
LinkedList *pre, *p, *r;
pre = h;
p = h->next;
while (p != NULL)
{
if (p->data % 2 == 0)
{ //判断,当p->data为偶数是,p继续往后扫描
p = p->next;
pre = pre->next;
}
//执行至此处,p标记的元素必为奇数
else
{
r = p; //贴标签
p = p->next;
pre->next = p;
free(r); //删除r标记的奇数
}
}
}
LinkedList *delodd2(LinkedList *h)
{ //头指针链表删除h中的所有奇数;
LinkedList *pre, *p, *r;
pre = h;
p = h->next;
//注意判断首元素是否为奇数,需要采用循环
while (pre->data % 2 != 0)
{ //判断首元素是否为奇数,若为奇数删除
r = pre;
p = p->next;
pre = pre->next;
h = pre; //由于首元素已经free,所以需要移动h,不然h是野指针
free(r);
}
//执行至此处pre标记的首元素为偶数
while (p != NULL)
{
if (p->data % 2 == 0)
{ //判断,当p->data为偶数是,p继续往后扫描
p = p->next;
pre = pre->next;
}
//执行至此处,p标记的元素必为奇数
else
{
r = p; //贴标签
p = p->next;
pre->next = p;
free(r); //删除r标记的奇数
}
}
return h;
}
int main()
{
LinkedList *h, *h1, *h2, *h3;
h1 = append2(); //创建头指针的单链表
printf("h1=: \n");
show2(h1);
// printf("将头指针单链表h中的所有奇数删除\n");
// h=delodd2(h);//注意有返回值是应采用h=delodd2(h);而不是直接delodd2(h),这样无法正确返回h
h2 = append2();
printf("h2=: \n");
show2(h2);
printf("将头指针单链表升序表h1,h2合并成降序表h3\n");
h3 = madeup2(h1, h2);
show2(h3);
// h=append();//尾插法创建头结点单链表
// h=crea_h();//头插法创建头结点单链表
// printf("h= ");
// show(h);
// printf("将h中的奇数删除\n");
// delodd(h);
// show(h);
// printf("将头结点单链表h中的最小值与首元素交换\n");
// findMin(h);
// printf("将头结点单链表h中的最小值插到表头\n");
// findMind(h);
// show(h);
// printf("头结点单链表在4后面插入5\n");
// find_in2(h,4,5);
// show(h);
// printf("头结点单链表删除h中的1\n");
// find_del(h,1);
// show(h);
// LinkedList *h1,*h2,*h3;
// h3=newNode;h3->next=NULL;
// printf("请输入头结点单链表升序表h1:\n");
// h1=append();
// printf("h1=: ");
// show(h1);
// printf("请输入头结点单链表升序表h2:\n");
// h2=append();
// printf("h2=: ");
// show(h2);
// printf("将h1,h2合并成头结点单链表升序表h3\n");
// madeup1(h1,h2,h3);
// printf("h3=: ");
// show(h3);
system("pause"); //暂停批文件处理,再继续处理之前等待按任意键,需在return 0之前。
return 0;
}
C语言数据结构单带头结点的链表和头指针型单链表的基本操作
最新推荐文章于 2024-05-02 08:56:15 发布