#include <malloc.h>
#include <stdlib.h>
#define ElemType int
typedef struct Node
{
ElemType data
struct Node * pNext
}NODE, * PNODE
PNODE create_list(void) //创建带有头结点的链表
void traverse_list(PNODE pHead) //遍历链表
bool is_empty(PNODE pHead) //判断链表是否为空
int length_list(PNODE pHead) //计算链表的长度
bool insert_list(PNODE pHead, int pos, int val) //向链表中制定位置插入数据
bool delete_list(PNODE pHead, int pos, int * val) //删除链表中指定位置的数据
void sort_list(PNODE pHead) //对链表进行排序 *** 作
PNODE check_list(PNODE pHead, ElemType value) //依据节点的数据值来查找数据
bool update_list(PNODE pHead, ElemType value1, ElemType value2) //更新数据
int main(void)
{
PNODE pHead = NULL //等价于struct Node * pHead = NULL
pHead = create_list() //创建一个非循环链表,并将该链表的头结点的地址赋值给头结点
traverse_list(pHead)
if (is_empty(pHead))
{
printf("链表是空的!\n")
}
else
{
printf("链表不为空!\n")
}
int len
printf("链表的长度是: %d\n", len = length_list(pHead))
sort_list(pHead)
traverse_list(pHead)
if(insert_list(pHead, 4, 5))
{
printf("数据插入成功!插入后的数据遍历结果为:\n")
traverse_list(pHead)
}
else
{
printf("数据插入失败!原始数据遍历结果为:\n")
traverse_list(pHead)
}
int val
if(delete_list(pHead, 4, &val))
{
printf("Success ->val is %d\n The result is :\n", val)
traverse_list(pHead)
}
else
{
printf("Faile!\n")
}
//做查询
printf("请输入要查询的数据:\n")
int value, value1
scanf("%d", &value)
if(NULL != check_list(pHead, value))
printf("链表中存在该数据!\n")
else
printf("链表中不存在该数据!\n")
//下面进行数据更新
printf("请输入被更新的数据及更新后的数据:\n")
scanf("%d %d", &value, &value1)
if(update_list(pHead, value, value1))
printf("The data is updated success!\n")
else
printf("The data is not updated!\n")
//数据更新后重新遍历链表
sort_list(pHead)
return 0
}
PNODE create_list(void)
{
int len //有效结点的个数
int i
int val //用来存储用户输入的结点的值
printf("请输入您要生成的链表的结点的个数:\n")
scanf("%d", &len)
//先生成一个头结点,然后在下面的for循环中将生成的临时结点链接进来就好了
PNODE pHead = (PNODE)malloc(sizeof(NODE))
if(NULL == pHead)
{
printf("内存分配失败,程序终止!\n")
exit(-1)
}
//pHead->data = len
//在for循环中进行挂结点的过程是,有一个尾指针pTail,每次创建新结点后,利用pTail->pNext = pNew pTail = pTail->pNext
PNODE pTail = pHead
pTail->pNext = NULL
for (i=0i<len++i)
{
printf("请输入第%d个结点的数值:", i+1)
scanf("%d", &val)
//数据接收异常处理
char ch
while((ch=getchar()) != '\n')
continue
//每循环一次就利用pNew获取一个新地址,并在pNew中存储数据,并将pNew挂到链表中去
PNODE pNew = (PNODE)malloc(sizeof(NODE))
if(NULL == pNew)
{
printf("分配失败,程序终止!\n")
exit(-1)
}
if(val == pTail->data)
{
printf("是否输入错误,本次输入数据与前者相同,请确认(如果正确输入Y,否则输入N):")
ch=getchar()
// printf("%c\n", ch)
if (ch =='N' || ch == 'n')
{
i--
continue
}
}
//利用尾指针进行挂结点的过程
printf("%d\n", val)
pNew->data = val
pTail->pNext = pNew
pTail = pNew
pTail->pNext = NULL
}
return pHead
}
void traverse_list(PNODE pHead)
{
PNODE p = pHead->pNext //这里一定要注意p是指pHead的指针域的值,而不是pHead后面的那个结点
while(NULL != p)
{
printf("%d\t", p->data)
p = p->pNext
}
printf("\n")
return
}
bool is_empty(PNODE pHead)
{
if(NULL == pHead->pNext)
return true
else
return false
}
int length_list(PNODE pHead)
{
int len = 0
PNODE p = pHead->pNext
//printf("")
while(NULL != p)
{
len++
p = p->pNext
}
return len
}
//在pHead所指链表的第pos个结点的前面插入一个新的结点,并且该结点的值是val;pos从1开始
bool insert_list(PNODE pHead, int pos, int val)
{
int i = 0 //用于统计链表中结点的个数,最终也就得到了链表的长度
PNODE p = pHead
while(NULL != p &&i <pos-1) //标识指针还有后续结点,并且i的数值要比pos小1
{
p = p->pNext
++i
}
//上面的循环中首先是i=0的时候,如果链表为空或者i>=pos-1(说明pos<=0)就直接往下走了,然后if成立,则退出程序;
//如果刚进入程序的时候没有退出,则说明pos是正数并且链表不为空。进去开始循环并利用i统计链表的长度,如果p=NULL先成立则说明pos数据过大;
//i永远不会大于pos,最好的情形就是碰到p=null,使得指针找到了要插入数据位置的前驱结点,方便后面进行插入
if(i>pos-1 || NULL==p)
return false
PNODE pNew = (PNODE)malloc(sizeof(NODE))
if(NULL == pNew)
{
printf("动态内存分配失败!\n")
exit(-1)
}
pNew->data = val
PNODE q = p->pNext
p->pNext = pNew
pNew->pNext = q
return true
}
bool delete_list(PNODE pHead, int pos, int * pVal)
{
int i = 0 //用于统计链表中结点的个数,最终也就得到了链表的长度
PNODE p = pHead
while(NULL != p &&i <pos-1) //标识指针还有后续结点,并且i的数值要比pos小1
{
p = p->pNext
++i
}
//上面的while循环最大可能就是造成 i=pos-1 或者 NULL= p
//如果i>pos-1则表示前面的while是由于NULL=p造成的,也就是说链表的长度要小于
if(i>pos-1 || NULL==p)
return false
PNODE q = p->pNext
*pVal = q->data
p->pNext = p->pNext->pNext
free(q)
q = NULL
return true
}
//不改变链表的指向,而是交换各个结点的数值
void sort_list(PNODE pHead) //非常的重要
{
int i, j, tmp, len = length_list(pHead)
PNODE p, q
for(i=0,p=pHead->pNexti<len-1++i,p=p->pNext)
{
for(j=i+1,q=p->pNextj<len++j,q=q->pNext)
{
if(p->data >q->data)
{
tmp = p->data
p->data = q->data
q->data = tmp
}
}
}
return
}
PNODE check_list(PNODE pHead, ElemType value)
{
PNODE p
while(pHead->pNext != NULL)
{
pHead = pHead->pNext
if(pHead->data == value)
{
p = pHead
return p
}
}
return p
}
bool update_list(PNODE pHead, ElemType value1, ElemType value2)
{
PNODE p = check_list(pHead, value1)
if(NULL == p)
{
return false
}
else
{
p->data = value2
}
return true
}
这个是一个还算完整的链表 *** 作的例子,有些功能是以前写的
你看看吧,应该符合你的要求
刚才忘记添加链表的销毁了
void destroy(PNODE pHead)
{
PNODE tmp = pHead
while(pHead->pNext != NULL)
{
tmp = pHead
pHead = pHead->pNext
free(tmp)
}
}
记得在前面进行函数声明
如果可以的话就采纳吧,嘿嘿
void del(Student *p1,Student *p2)是不是得加个num的输入void del(Student *p1,Student *p2,int num)
或者下面改成p1->num!=p2->num?
没细看
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)