单链表由多个结点构成,每个结点有数据域和指针域。指针域的指针指向其后继的结点。最后一个结点的指针域指针指向NULL。
头结点的数据域存放长度。
头文件head.h
#ifndef _HEAD_H
#define _HEAD_H
typedef struct node* List;
typedef int ElementType;
typedef struct node {
ElementType data;
List next;
}Node;
/*创建链表, 表长为length*/
List CreateList(int length);
/*插入数据*/
void InsertNode(List head, int n);
/*删除数据*/
void DeleteNode(List head, int n);
/*修改数据*/
void ModifyNode(List head, int n);
/*查找数据*/
List FindData(const Node* head, ElementType n);
/*释放内存*/
void FreeSpace(List head);
/*显示*/
void Display(const Node* head);
/*清除缓冲区*/
void clean(void);
/*判断是空*/
int IsEmpty(const Node* head);
/*输入函数,加了输入限制保证不越界*/
int Input(const Node* l);
#endif
主函数main.c
#include<stdio.h>
#include"head.h"
int main(void)
{
int location = 0; //位置,后面要用到
printf("创建一个初始链表,你想有几个结点:\n");
int n;
scanf("%d", &n);
clean();
List head = CreateList(n);
Display(head);
puts("*****************************************");
printf("插入操作\n");
location = Input(head);
InsertNode(head, location - 1);
Display(head);
puts("*****************************************");
printf("删除操作\n");
location = Input(head);
DeleteNode(head, location - 1);
Display(head);
puts("*****************************************");
printf("修改操作\n");
location = Input(head);
ModifyNode(head, location - 1);
Display(head);
puts("*****************************************");
printf("查找操作\n");
ElementType find;
printf("输入你要查找的值:");
scanf("%d", &find);
clean();
List p = FindData(head, find);
printf("%d\n", p == NULL ? printf("没有这个数据\n") : p->data);
puts("*****************************************");
Display(head);
FreeSpace(head);
return 0;
}
操作集operation.c
不考虑分配不到内存的情况。
#include"head.h"
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
List CreateList(int length)
{
srand((unsigned int)time(0)); //种子设置为系统时间
List head = (List)malloc(sizeof(Node)); //头结点,准确来说head是指向头结点的头指针,但是这里头结点也是malloc的了。如果有必要可以在主函数里Node head一个头结点。
head->data = 0;
head->next = NULL;
List record = head;
while(length--)
{
List p = (List)malloc(sizeof(Node));
p->data = rand() % 10; //生成不大于10的随机种子
p->next = NULL;
record->next = p;
record = p;
head->data++;
}
return head;
}
int Input(const Node* l)
{
printf("选择位置:");
int location;
while(scanf("%d", &location))
{
if (location > 0 && location <= l->data)
break;
printf("选择位置, 不小于1, 不大于%d:", l->data);
clean();
}
clean();
return location;
}
void InsertNode(List head, int n)
{
while(n--)
{
head = head->next;
}
List p = (List)malloc(sizeof(Node));
printf("插入的值:\n");
scanf("%d", &p->data);
clean();
p->next = head->next;
head->next = p;
head->data++;
}
void DeleteNode(List head, int n)
{
List h = head;
List front = head;
head = head->next; //head指向第一个有效值的位置
while(n--)
{
front = head;
head = head->next;
}
front->next = head->next;
free(head);
h->data--;
}
void ModifyNode(List head, int n)
{
List l = head->next;
while(n--)
{
l = l ->next;
}
printf("要修改的值:\n");
scanf("%d", &l->data);
}
List FindData(const Node* head, ElementType n)
{
List l = head->next;
while(l)
{
if (l->data == n)
return l;
l = l->next;
}
printf("没有这个数据\n");
return NULL;
}
void FreeSpace(List head)
{
List p = head->next;
List q = head;
while(p)
{
q = p->next;
free(p);
p = q;
}
free(head);
}
void Display(const Node* head)
{
int length = head->data;
if (IsEmpty(head))
{
printf("Is Empty");
exit(EXIT_FAILURE);
}
List l = head->next;
/*
for (int i = 1; l; i++)
{
printf("%2d", l->data);
l = l->next;
if (i % 10 == 0)
{
printf("\n");
i = 0;
}
}
*/
for (int i = 1; i <= length; i++)
{
printf("%2d", l->data);
if (i != length) //表示到达最后一个
printf("->");
l = l->next;
}
printf("\n");
return ;
}
void clean(void)
{
while(getchar() != '\n')
continue;
}
int IsEmpty(const Node* head)
{
return head->next == NULL;
}
这里为什么要搞一个const Node *,而不是const List,可以看下面这篇文章:
链接:typedef