实现了以下功能:
- 初始化带头结点的链表
- 判断链表是否为空
- 头插法建立单链表
- 尾插法建立单链表
- 单链表按值查找
- 单链表按序号查找
- 单链表插入——后插法
- 单链表插入——前插法
- 单链表的删除——删除p的后继
- 单链表的删除——删除p本身
- 单链表的删除——删除值为x 的结点
- 单链表的打印
#include<stdio.h>
#include<stdlib.h>
#include <windows.h>
#define FALSE 0
#define TRUE 1
typedef int DataType;
typedef struct Node
{
DataType info;
struct Node *link;
}QNode;
typedef struct Node *PNode;
typedef struct Node *LinkList;
// 初始化带头结点的链表
LinkList initList()
{
LinkList head = (QNode*)malloc(sizeof(QNode));
if (head == NULL)
{
exit(0);
}
head->link = NULL;
return head;
}
// 判断链表是否为空
int isNullList_link(LinkList llist)
{
return(llist->link == NULL);
}
// 头插法建立单链表
void createListHead(LinkList head)
{
PNode p = NULL;
int data;
head->link = NULL;
printf("请输入整型数据建立链表,以-1结束:\n");
scanf("%d", &data);
if (data == -1)
{
printf("该链表为空链表。\n");
}
while(data != -1)
{
p = (QNode *)malloc(sizeof(QNode));
p->info = data;
p->link = head->link;
head->link = p;
scanf("%d", &data);
}
}
// 尾插法建立单链表
void createListTail(LinkList head)
{
PNode p = NULL;
PNode rear = head;
int data;
printf("请输入整型数据建立链表,以-1结束:\n");
scanf("%d", &data);
if (data == -1)
{
printf("该链表为空链表。\n");
}
while(data != -1)
{
p = (QNode *)malloc(sizeof(QNode));
p->info = data;
p->link = NULL;
rear->link = p;
rear = p;
scanf("%d", &data);
}
}
// 单链表按值查找
// 查找过程从开始结点出发,顺着链逐个将结点的值与给定值x比较。
PNode Locate_link(LinkList llist, DataType x)
{
PNode p = NULL;
if(llist->link == NULL)
{
printf("该链表为空链表\n");
exit(0);
}
p = llist->link;
while((p != NULL) && (p->info != x))
{
p = p->link;
if(p->info != x && p->link == NULL)
{
printf("没有找到该节点。\n");
return NULL;
}
}
return p;
}
// 单链表按序号查找
// 在链表中查找第i个结点,有的话返回该结点存储位置。否则返回NULL
PNode Num_link(LinkList llist, int i)
{
int count=1;
PNode p = NULL;
p = llist->link;
if(llist->link == NULL)
{
printf("该链表为空链表\n");
exit(0);
}
if(i == 1)
return llist->link;
while(count < i)
{
p = p->link;
count++;
if(count == i)
{
printf("第%d位元素为(以第1位为始):%d\n", i, p->info);
return p;
}
if(p->link == NULL)
{
printf("该链表无第%d位,查找的值有误。\n", i);
exit(0);
}
}
}
// 单链表插入——后插法
// 看起来是先通过两种方式查找到一个指针。然后在这个位置后插入新的结点
int insertPost_link(LinkList llist, PNode p, DataType x)
{
PNode q = (QNode *)malloc(sizeof(QNode));
if(q == NULL)
{
printf("空间溢出。\n");
return FALSE;
}
else
{
q->info = x;
q->link = p->link;
p->link = q;
return TRUE;
}
}
// 单链表插入,前插法
// 看起来是先通过两种方式查找到一个指针。然后在这个位置前插入新的结点
int insertQian_link(LinkList llist, PNode p, DataType x)
{
PNode r = NULL;
PNode q = (QNode *)malloc(sizeof(QNode));
if (q == NULL)
{
printf("空间溢出。\n");
return FALSE;
}
else
{
r = llist;
while(1)
{
if (r->link == p)
{
q->info = x;
q->link = r->link;
r->link = q;
return TRUE;
}
else
r = r->link;
}
}
}
// 单链表的删除——删除p的后继
int deletePAft_link(LinkList llist, PNode p)
{
PNode q;
if(p->link == NULL)
{
printf("该结点无后继结点。\n");
return FALSE;
}
else
{
q = p->link;
p->link = q->link;
free(q);
return TRUE;
}
}
// 单链表的删除——删除p本身
int deletePPre_link(LinkList llist, PNode p)
{
PNode q = NULL;
q = llist;
while(1)
{
if (q->link == p)
{
q->link = p->link;
free(p);
return TRUE;
}
else
q = q->link;
}
}
// 单链表的删除——删除值为x的结点
int deleteV_link(LinkList llist, DataType x)
{
PNode p, q;
p = llist;
if(p == NULL)
return FALSE;
while((p->link != NULL) && (p->link->info != x))
p = p->link;
if(p->link == NULL)
{
printf("要删除的结点不存在。\n");
return FALSE;
}
else
{
q = p->link;
p->link = q->link;
free(q);
return TRUE;
}
}
// 单链表的打印
void print(LinkList llist)
{
PNode p = NULL;
p = llist->link;
if(p == NULL)
{
printf("该链表为空。\n");
exit(0);
}
while(p->info != NULL)
{
printf("%d\t", p->info);
if (p->link != NULL)
p = p->link;
else
{
printf("\n");
break;
}
}
}
int main()
{
LinkList lx_alist1, lx_alist2;
PNode p;
int num,len,i,x,q;
int temp;
int j,k;
lx_alist1 = initList();
lx_alist2 = initList();
printf("判断链表是否为空(1为空):%d\n", isNullList_link(lx_alist1));
printf("\n ====== 头插法创建链表: ====== \n");
createlisthead(lx_alist1);
print(lx_alist1);
printf("\n ====== 尾插法创建链表: ====== \n");
createListTail(lx_alist2);
print(lx_alist2);
printf("\n ====== 按值查找: ====== \n");
p = Locate_link(lx_alist2, 2);
if(p != NULL)
{
printf("已成功找到该结点位置。\n");
}
else
printf("该链表中无此值。\n");
printf("\n ====== 按序号查找: ====== \n");
num = 1;
p = Num_link(lx_alist2, num);
printf("OK\n");
printf("\n ====== 单链表的插入,后插法: ====== \n");
num = 11;
q = insertPost_link(lx_alist2, p, num);
print(lx_alist2);
printf("\n ====== 单链表的插入,前插法: ====== \n");
num = 12;
q = insertQian_link(lx_alist2, p, num);
print(lx_alist2);
printf("\n ====== 单链表的删除,删除值为x的结点: ====== \n");
num = 5;
q = deleteV_link(lx_alist2, num);
print(lx_alist2);
printf("\n ====== 单链表的删除,删除p的后继: ====== \n");
q = deletePAft_link(lx_alist2, p);
print(lx_alist2);
printf("\n ====== 单链表的删除,删除p本身: ====== \n");
q = deletePPre_link(lx_alist2, p);
print(lx_alist2);
system("pause");
return 0;
}
初学数据结构,部分函数代码可能不是很简洁。轻喷。