c语言链表的基本操作2
#include <stdio.h>
#include <stdlib.h>
typedef int Datatype; //如果存其他类型的数据可以在此处直接修改
typedef struct node {
Datatype data;
struct node *next;
}Node;
//创建结点
Node* creatNode(Datatype data) {
Node* p = NULL;
p = (Node*)malloc(sizeof(Datatype)); //申请内存
if (p == NULL) { //安全检查
return NULL;
}
p->data = data; //赋值
p->next = NULL;
return p;
}
//打印链表
void printList(Node* head) {
Node* p = head;
if (head == NULL) {
return;
}
while(p != NULL) {
printf("%d\n",p->data);
p = p->next;
}
return;
}
//在一个结点后插入新结点
int insertNodeBehind(Node* p,Node* pnew) {
if (p == NULL || pnew == NULL) {
return -1;
}
if (p->next != NULL) {
pnew->next = p->next;
p->next = pnew;
}
else {
p->next = pnew;
}
/*其实此处直接写
pnew->next = p->next;
p->next = pnew;
就可以了,因为若p->next = NULL则pnew->next = NULL*/
return 0;
}
//结点后插入一个数据
int insertDataBehind(Node *p,Datatype data) {
Node* pnew = NULL;
if (p == NULL) {
return -1;
}
pnew = creatNode(data);
insertNodeBehind(p,pnew);
return 0;
}
//返回最后末尾结点的地址
Node* findListTail(Node* phead) {
if (phead == NULL) {
return NULL;
}
while (phead->next != NULL) {
phead = phead->next;
}
return phead;
}
//插入数据到链表的末尾,**是因为可能会涉及修改头指针,在没有结点的情况下
int listInsertDataAtTail(Node** phead,Datatype data) {
Node *p = NULL;
if (phead == NULL) {
return -1;
}
if (*phead == NULL) {
*phead = creatNode(data);
return 0;
}
p = findListTail(*phead);
insertDataBehind(p,data);
return 0;
}
//删除后一个结点
int deleteNodeBehind(Node* p) {
Node* temp = NULL;
if (p == NULL) {
return -1;
}
if (p->next == NULL) {
return 1;
}
temp = p->next;
p->next = p->next->next;
free(temp);
return 0;
}
//返回数据为data的结点的地址
Node* findNode(Node* head,Datatype data) {
Node* p = NULL;
if (head == NULL) {
return NULL;
}
p = head;
while (p->data != data) {
if (p->next != NULL) {
p = p->next;
}
else {
return NULL; //没找到该数据为data的结点
}
}
return p;
}
//改数据
int listChangeData(Node* head,Datatype oldData,Datatype newData) {
Node* p = NULL;
if (head == NULL) {
return -1;
}
p = findNode(head, oldData);
p->data = newData;
return 0;
}
//返回数据为data的结点的前一个结点的地址
Node* findPrevNode(Node *head,Datatype data) {
Node* p = NULL;
if (head == NULL) {
return NULL;
}
p = head;
while (p->next != NULL) {
if (p->next->data == data) {
return p;
}
else {
p = p->next;
}
}
return NULL;
}
//删除链表中第一个数据为data的结点
int listDeleteData(Node** phead,Datatype data) {
Node* p = NULL;
Node* temp = NULL;
if (phead == NULL || *phead == NULL) {
return -1;
}
if ((*phead)->data == data) {
temp = (*phead);
(*phead) = (*phead)->next;
free(temp);
return 0;
}
p = findPrevNode(*phead, data);
deleteNodeBehind(p);
free(temp);
return 0;
}
//销毁链表
int listDestroy(Node **phead) {
if (phead == NULL || (*phead) == NULL) {
return 0;
}
while ((*phead)->next != NULL) {
deleteNodeBehind(*phead);
}
(*phead) = NULL;
free(*phead); //不知道此处有没有错误!
return 0;
}
int main(int argc, const char * argv[]) {
// 创建结点,查尾,增加结点
Node* p = NULL;
listInsertDataAtTail(&p, 1); //调用了creatNode,findListTail,insertNodeBehind
printList(p);
listInsertDataAtTail(&p, 2);
listInsertDataAtTail(&p, 3);
listInsertDataAtTail(&p, 4);
listInsertDataAtTail(&p, 5);
printf("已有节点:1-2-3-4-5\n");
printList(p);
// 删除
// printf("删除1后面结点\n");
// listDeleteData(&p, 1);
// listDeleteData(&p, 3);
// printList(p);
// 修改
printf("修改2为20000\n");
listChangeData(p, 2, 20000);
printList(p);
listDestroy(&p);
printList(p);
return 0;
}