#include <stdio.h>
#include <stdlib.h>
struct Node
{
int value;
struct Node *next;
};
//增
struct Node *increaseFromBehand(struct Node *head, int data, struct Node *new)
{
struct Node *phead = head;
if(head == NULL){
printf("link is empty,not increase\n");
}
while(phead != NULL){
if(data == phead->value){
new->next = phead->next; //等号的左边是变量,等号的右边是值(赋值语句)
phead->next = new;
return head;
}
phead = phead->next;
}
printf("链表中没有%d,不能在其后面插入\n",data);
return head;
}
struct Node *increaseFromForword(struct Node *head, int data, struct Node *new)
{
struct Node *phead = head;
if(data == phead->value){
new->next = phead;
head = new;
return head;
}
while(phead->next !=NULL){
if(data == phead->next->value){
new->next = phead->next;
phead->next = new;
return head;
}
phead = phead->next;
}
printf("链表中没有%d,不能在其前面插入\n",data);
return head;
}
//删
struct Node *deleteNode(struct Node *head, int data)
{
struct Node *phead = head;
if(head == NULL){
return head;
}
if(data == phead->value){
head = phead->next;
free(phead);
return head;
}
while(phead->next != NULL){
if(data == phead->next->value){
struct Node *temp = NULL;
temp = phead->next;
phead->next = phead->next->next;
free(temp);
return head;
}
phead = phead->next;
}
printf("链表中没有%d,不能从链表中删除\n",data);
return head;
}
//改
struct Node *modifyLink(struct Node *head, int destdata, int sourcedata)
{
struct Node *phead = head;
while(phead != NULL){
if(sourcedata == phead->value){
phead->value = destdata;
return head;
}
phead = phead->next;
}
printf("没有找到要更改的数\n");
return head;
}
//查
int checkLink(struct Node *head, int data)
{
while(head != NULL){
if(data == head->value){
return 1;
}
head = head->next;
}
return 0;
}
//反转
struct Node *invertlink(struct Node *head)
{
if(head == NULL){
printf("空链表\n");
return NULL;
}
if(head->next == NULL){
return head;
}
struct Node *p;
struct Node *q;
p = head->next;
head->next = NULL;
while(p != NULL){//p用来遍历链表
q = p;
p = p->next;
q->next = head;
head = q;
//p = p->next; 放在这里不得行,因为q->next = head;,这样p不是指向下一个,而是指向了head的下一个
}
return head;
}
//计算节点个数
int calculateCont(struct Node *head)
{
int cnt = 0;
if(head ==NULL){
return 0;
}
while(head != NULL){
cnt++;
head = head->next;
}
return cnt;
}
//头插法创建链表
struct Node *insertFromHead(struct Node *head,struct Node *new)
{
struct Node *phead = head;
if(head == NULL){
head = new;
}else{
new->next = head;
head = new;
}
return head;
}
//尾插法创建链表
struct Node *insertFromTail(struct Node *head, struct Node *new)
{
struct Node *phead = head;
if(head == NULL){
head = new;
}else{
while(phead->next != NULL){
phead = phead->next; //找最后的那个节点
}
phead->next = new;
}
return head;
}
struct Node *createLinkFromHead(struct Node *head)
{
struct Node *new;
while(1){
new = (struct Node *)malloc(sizeof(struct Node));
printf("please input data:\n");
scanf("%d",&(new->value));
new->next = NULL;
if(new->value == 0){
printf("create complete\n");
free(new);
return head;
}
head = insertFromHead(head, new);
}
}
struct Node *createLinkFromTail(struct Node *head)
{
struct Node *new;
while(1){
new = (struct Node *)malloc(sizeof(struct Node));
printf("please input data:\n");
scanf("%d",&(new->value));
new->next = NULL;
if(new->value == 0){
printf("create complete\n");
free(new);
return head;
}
head = insertFromTail(head, new);
}
}
void printLink(struct Node *head)
{
if(head == NULL){
printf("input link is empty\n");
}
while(head != NULL){//找最后一个节点
printf("%d ",head->value);
head = head->next;
}
printf("\n");
}
int main()
{
//创建
struct Node *head = NULL;
head = createLinkFromTail(head);
printf("链表中节点个数 = %d\n",calculateCont(head));
printLink(head);
printf("\n");
//增加节点
struct Node new2 = {1005,NULL};
head = increaseFromForword(head, 3, &new2);
printf("链表中节点个数 = %d\n",calculateCont(head));
printLink(head);
printf("\n");
struct Node new1 = {1000,NULL};
head = increaseFromBehand(head, 3, &new1);
printf("链表中节点个数 = %d\n",calculateCont(head));
printLink(head);
printf("\n");
//删除节点
head = deleteNode(head, 3);
printf("链表中节点个数 = %d\n",calculateCont(head));
printLink(head);
printf("\n");
//修改节点
head = modifyLink(head, 1006, 6);
printf("链表中节点个数 = %d\n",calculateCont(head));
printLink(head);
printf("\n");
//检查节点
if(checkLink(head, 1001)){
printf("链表中有该数据\n");
}else{
printf("链表中无该数据\n");
}
printf("链表中节点个数 = %d\n",calculateCont(head));
return 0;
}
//这种遍历方式能变量完整个链表,且链表中的每个节点都操作(如每个节点的值都能输出),但最后head会指向NULL
while(head != NULL){
head = head->next;
}
//这种遍历方式也能变量完整个链表,但链表的最后一个节点不能操作(如不能输出最后一个节点的值),最后head会指向最后一个节点
//这种遍历方式在删除一个节点、在一个节点前面插入一个节点、尾插法创建一个链表时适用。
//因为删除一个节点、在一个节点前面插入一个节点都要明确找到的那个节点的前一个节点,这样才能正确操作。
//尾插法创建一个链表,就要让head指向最后的那个节点,这样就可以在最后的节点后插入
while(head->next != NULL){
head = head->next;
}