C语言学习——单链表
2016-03-13 10:08
357 查看
今天学习了单链表的增(创建)删改查的操作。
创建链表,共有头插法、尾插法、和有序插入法(中间插入)三种。
1.头插法创建无头链表(头节点中存数据):无头链表似乎在其他的操作上会比较麻烦,因为要单独处理头节点的数据。
2.尾插法创建有头链表(头节点中不存数据,仅指向下一个节点的指针)
有头链表与无头链表的区别:
在遍历元素的时候:
有头:
Node *temp;
temp=head->next; //无头:temp=head;
while(temp!=NULL){
......
temp=temp->next;
}
创建链表,共有头插法、尾插法、和有序插入法(中间插入)三种。
1.头插法创建无头链表(头节点中存数据):无头链表似乎在其他的操作上会比较麻烦,因为要单独处理头节点的数据。
#include <stdio.h> #include <stdlib.h> struct node{ int data; struct node *next; }; void link_head_insert(struct node** phead,struct node** ptail,int n){ struct node* pnew = (struct node*)malloc(sizeof(struct node)); memset(pnew, 0, sizeof(struct node)); pnew->data = n; if (*phead == NULL){ *phead = pnew; *ptail = pnew; } else{ pnew->next = *phead; *phead = pnew; } } void link_print(struct node* phead){ struct node* pcur; pcur = phead; while (pcur != NULL){ printf("%3d ", pcur->data); pcur = pcur->next; } printf("\n"); } int main(){ struct node *phead, *ptail; int num; phead = NULL; ptail = NULL; while (scanf("%d", &num) != EOF){ link_head_insert(&phead, &ptail, num); } link_print(phead); reverse(phead); link_print(phead); system("pause"); return 0; }
2.尾插法创建有头链表(头节点中不存数据,仅指向下一个节点的指针)
#include <stdio.h> #include <stdlib.h> typedef struct node{ int data; struct node *pNext; }Node,*pNode; pNode creatList(pNode pHead){ //尾插法 int i, len, val; //len是链表节点数,val是节点data值 pHead = (pNode)malloc(sizeof(Node)); //给头节点分配空间 pNode pTail = pHead; //定义尾节点,初始化在头节点 pTail->pNext = NULL; //尾节点的指针为空 printf("请输入节点个数:"); scanf("%d", &len); for (i = 0; i < len; ++i){ printf("第 %d 个节点的数值:", i + 1); scanf("%d", &val); pNode pNew = (pNode)malloc(sizeof(Node)); //为各节点分配空间 pNew->data = val; pTail->pNext = pNew; pNew->pNext = NULL; pTail = pNew; } return pHead; } void printList(pNode pHead){ pNode p = pHead->pNext; while (NULL != p){ printf("%d ", p->data); p = p->pNext; } printf("\n"); } void reverse(struct node* head)//单链表的倒置算法 { struct node *p, *q; p = head->pNext; head->pNext = NULL; while (p) { q = p->pNext; p->pNext = head->pNext; head->pNext = p; p = q; } } void findReverse4(pNode pHead){ //找出链表的倒数第四个节点:先反转,再顺序读第四个节点 reverse(pHead); pNode p = pHead->pNext; int cnt=1; while (NULL != p){ cnt++; p = p->pNext; if (cnt < 4) continue; else if (cnt == 4) printf("%d\n", p->data); } if (cnt <= 4) printf("节点数不足4个\n"); } void findMid(pNode pHead){ //找出链表的中间节点 pNode p = pHead->pNext; int cnt = 0, mid; while (NULL != p){ cnt++; p = p->pNext; } mid = cnt/2; p = pHead->pNext; cnt = 0; while (NULL != p){ if (cnt == mid) printf("%d\n", p->data); cnt++; p = p->pNext; } } //using step1 and step2 here 使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p == q,则存在环。 //if exists a loop, then the pointer which use step2 will catch up with the pointer which uses step1 void has_loop(pNode head){ pNode p = head; pNode q = head; while (p != NULL && q != NULL){ /* p = p->next; (q->next != NULL) q = q->next->next; if (p == q) return 1; */ //correct it on 17/11/2012 p = p->pNext; q = q->pNext; if (q != NULL) q = q->pNext; if (p != NULL && p == q) printf("has loop\n"); } printf("no loop\n"); } int main(){ pNode pHead = NULL; pHead = creatList(pHead); printList(pHead); //reverse(pHead); //printList(pHead); //findReverse4(pHead); //findMid(pHead); has_loop(pHead); system("pause"); return 0; }
有头链表与无头链表的区别:
在遍历元素的时候:
有头:
Node *temp;
temp=head->next; //无头:temp=head;
while(temp!=NULL){
......
temp=temp->next;
}
相关文章推荐
- C++设计模式编程中使用Bridge桥接模式的完全攻略
- C++ Primer 5th - 1.1.1 编译并且运行我们的程序
- C/C++之FILE文件流的中fopen、fread、fseek、fclose的使用
- 关于C语言中 字符串常量的问题
- C语言小结2
- C语言(关键字const)
- C++ IO库之学习笔记(第八章)
- C++ Exceptinal 类之间的关系
- C++ Exceptional 类的重载、重写(覆盖)和隐藏
- Windows下Eclipse for C/C++的“Launch failed. Binary not found”完美解决方案
- C++第1次实验—复习-函数T 1
- C++ Primer Plus (第六版)之旅 第三章01
- c++的一个求最大公约数和最小公倍数的简单程序,求给点意见!
- c++第一次上机报告2
- c/c++头文件的作用
- c语言:通过指针变量访问整型变量
- C++数列求和
- C++处理异常技巧-try,catch,throw,finally
- C++ const用法 尽可能使用const
- C++学习笔记之多态与虚函数,虚函数表