1.题目:单链表操作
功能: 1. 建立一个含有若干个整数的单链表存储结构;
2. 输出单链表各节点的值;
3. 查询第i个结点的值,并输出;
4. 在第i个结点之后插入一个值为key的结点。
5. 删除第i个结点。
要求:利用指针、动态存储分配(malloc)建立单链表。利用菜单可以循 环实现各个功能。
进一步要求*: (1) 能够实现单链表的逆序;
(2) 能够实现单链表的排序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define len sizeof(struct link)
typedef struct link{
int x;
struct link *next;
}node;
node *head = NULL; //head为全局变量,方便函数使用
int n; //节点数
void show(); //显示各个节点的值
void create(); //创建单链表
void find(); //查询单链表的节点的值
void insert(); //插入节点
void del(); //删除某个节点
void change(); //对链表排序
void reve(); //实现链表逆序
int main() {
while(1) {
printf (" 菜单\n");
printf ("¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥\n");
printf (" 1. 建立一个单链表\n");
printf (" 2. 输出单链表各节点的值\n");
printf (" 3. 查询第i个结点的值,并输出\n");
printf (" 4. 在第i个结点之后插入一个值为key的结点\n");
printf (" 5. 删除第i个结点\n");
printf (" 6. 对链表排序\n");
printf (" 7. 实现链表的逆序\n");
printf (" 0. 退出\n");
printf ("¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥\n");
printf ("请输入:");
int k;
scanf ("%d", &k);
getchar();
switch(k) {
case 0: exit(0);
case 1: {
create(); break;
}
case 2: {
show(); break;
}
case 3: {
find(); break;
}
case 4: {
insert(); break;
}
case 5: {
del(); break;
}
case 6: {
change(); break;
}
case 7: {
reve(); break;
}
}
}
return 0;
}
//输出链表各个节点的值
void show() {
node *p1 = head;
if(head != NULL) {
while(p1 != NULL) {
printf("%-5d", p1->x);
p1=p1->next;
}
printf("\n");
} else {
puts("空链表");
}
}
//建立链表
void create() {
node *p1,*p2;
p1 = p2 = (node*)malloc(len);
printf("输入数字,回车键结束\n");
char c = 'a';
while(c != '\n')
{
scanf("%d%c", &p1->x, &c);
p2 = p1;
if (head == NULL) head = p1;
p1 = (node*)malloc(len);
p2->next = p1;
n++;
}
p2->next = NULL;
free(p1);
}
//查询第i个结点的值,并输出\n"
void find() {
// 防止链表为空
if (head == NULL) {
printf ("链表为空,请建立链表\n");
return;
}
node *p = head;
printf ("一共%d个节点,输入要查询的节点i\n", n);
int i, j = 1; scanf ("%d", &i);
while (i > n || i < 1) {
printf("输入数据不符合,重新输入\n");
scanf ("%d", &i);
}
while (j < i && p != NULL) {
p = p->next;
j++;
}
printf ("%d\n", p->x);
}
//在第i个结点之后插入一个值为key的结点
void insert() {
// 防止链表为空
if (head == NULL) {
printf ("链表为空,请建立链表\n");
return;
}
node *p = head, *pnew, *t = head;
printf ("一共%d个节点,输入要插入的节点i(0--%d)和数值k\n", n, n);
int i, k, j = 1; scanf ("%d %d", &i, &k);
while (i > n || i < 0) {
printf("输入数据不符合,重新输入\n");
scanf ("%d %d", &i, &k);
}
pnew = (node*)malloc(len); pnew->x = k;
//进行插入操作
while (j < i) {
p = p->next;
j++;
}//i = 0插入到头结点
if (i == 0) {
head = pnew;
pnew->next = p;
}//尾节点
else if (i == n) {
p->next = pnew;
pnew->next = NULL;
}//中间
else {
t = p->next;
p->next = pnew;
pnew->next = t;
}
//插入完成节点数加一
n++;
printf ("插入后链表为:\n");
show();
}
//删除第i个结点
void del() {
// 防止链表为空
if (head == NULL) {
printf ("链表为空,请建立链表\n");
return;
}
//t指针在后,p指针在前
node *p = head, *t = head;
printf ("一共%d个节点,输入要删除的节点i\n", n);
int i, j = 1; scanf ("%d", &i);
while (i > n || i < 1) {
printf("输入数据不符合,重新输入\n");
scanf ("%d", &i);
}
while(i > j) {
t = p;
p = p->next;
j++;
}
//头结点
if (i == 1) {
head = p->next;
free(p); n--;
}
//尾节点
else if (i == n) {
t->next = NULL;
free(p); n--;
}
//中间结点
else {
t->next = p->next;
free(p); n--;
}
printf ("删除后链表为:\n");
show();
}
//对链表排序
void change() {
// 防止链表为空
if (head == NULL) {
printf ("链表为空,请建立链表\n");
return;
}
node *t = head, *p = t->next;
int temp;
//排序
while(t != NULL) {
while(p != NULL) {
if(t->x > p->x) {
temp = t->x; t->x = p->x; p->x = temp;
}
p=p->next;
}
t = t->next;
if(t != NULL)
p = t->next;
else
p = NULL;
}
printf ("排序后链表为:\n");
show();
}
//逆序链表
void reve() {
// 防止链表为空
if (head == NULL) {
printf ("链表为空,请建立链表\n");
return;
}
//t 存储 q->next 然后使q->next指向前一个节点p
//再使 p = q ,p移到当前节点,q = t 使q指向下一个节点
//以此类推至到 q = NULL,此时p为新的头指针
node *p = NULL, *t = NULL, *q = head;
while (q != NULL) {
t = q->next;
q->next = p;
p = q;
q = t;
}
head = p;
printf ("逆序后链表为:\n");
show();
}