今天搞了一个多小时,头是疼的,应该是没休息好吧,学习了数据结构这一节,感觉收益良多,下面贴上代码和心得:
1 /*24_链表创建和链表遍历算法的演示*/ 2 # include <stdio.h> 3 # include <malloc.h> 4 # include <stdlib.h> 5 6 typedef struct Node 7 { 8 int data;//数据域 9 struct Node * pNext;//指针域 10 }NODE, *PNODE;//NODE等价于struct Node 11 12 //函数声明 13 PNODE create_list(void); 14 void traverse_list(PNODE pHead); 15 16 int main(void) 17 { 18 PNODE pHead = NULL;//等价于 struct Node * pHead = NULL;把首节点的地址赋值给pHead(在一个链表中首节点和尾节点后面都是NULL,没有其他元素) 19 //PNODE 等价于struct Node * 20 pHead = create_list(); 21 traverse_list(pHead); 22 23 24 return 0; 25 } 26 27 //创建地址类型的地址,因为create_list 这个函数是要返回的地址 28 //功能就是把头节点的地址返回,最终才能头节点才能指向一个链表 29 PNODE create_list(void) 30 { 31 int len;//存放有效节点的个数 32 int i; 33 int val;//用来临时存放用户熟入的节点是值 34 35 //前面说过只要是找到头节点,对于链表的操作就方便了,所以在这里我们首先先定义头节点 36 PNODE pHead = (PNODE)malloc(sizeof(NODE));//定义头节点(不存放有效数据) 37 if (NULL == pHead) //如果指针指向为空,则动态内存分配失败 38 { 39 printf("分配失败,程序终止!\n"); 40 exit(-1); 41 } 42 PNODE pTail = pHead; //pHead 是指向头节点的,如果用户是输入节点的个数是0,那么只有一个“头节点” 43 pTail->data = NULL; //此时把pHead 赋值给pTail,则就合理l,然后指针域为空(和初始化差不多...) 44 45 printf("请您输入要生成链表节点的个数:len = "); 46 scanf("%d", &len); 47 for (i = 0; i < len; i++) 48 { 49 printf("请输入第%d个节点的值",i + 1); 50 scanf("%d", &val); 51 PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建新节点,使之指针都指向每一个节点(循环了len次) 52 if (NULL == pNew) //如果指针指向为空,则动态内存分配失败 53 { 54 printf("分配失败,程序终止!\n"); 55 exit(-1); 56 } 57 /* 58 59 pNew->data = val;//一个临时的节点 60 pHead->pNext = pNew;//把pNew挂到pHead上 61 pNew->pNext=NULL; //这个临时的节点最末尾是空 62 63 */ 64 65 66 //上面/**/注释掉的这行代码是有问题的,上面注释掉的代码的含义是分别把头节点后面的节点都挂在头节点上, 67 //导致头节点后面的节点的指针域丢失,而我们想的是只是把第一个节点挂在头节点上,后面的依次进行,即把第二个 68 //节点挂在第一个节点的指针域上,依次类推,很明显上面所注释掉的代码是实现不了这个功能的 69 70 //下面是改进之后的 71 pNew->data = val; //把有效数据存入pNEW 72 pTail->pNext = pNew; //把pNew 挂在pTail的后面(也就是pTail指针域指向,依次串起来) 73 pNew->pNext = NULL;//把pNew的指针域清空 74 pTail = pNew; //在把pNew赋值给pTai,这样就能循环,实现依次连接(而我们想的是只是把第一个节点挂在头节点上,后面的依次进行,即把第二个 75 //节点挂在第一个节点的指针域上) 76 } 77 return pHead; 78 } 79 80 81 //遍历函数并不需要返回值,参数还是要有的,要不然怎么知道是对哪个对象进行的遍历! 82 //还是定义指针变量 PNODE pHead 因为 traverse_list(pHead) 调用的是地址 83 84 85 /* 86 链表的遍历写法的整体思路: 87 1. 定义一个指针变量p指向第一个有效的节点 88 2.判断这个节点的指针域是不是为空(如果不是就不是最后一个) 89 3.不为空就输出此节点的有效数据,并且p-pNext来指向下一个节点(不能用p++哦!) 90 4.如果为空的话,说明到来尾节点 91 */ 92 93 94 void traverse_list(PNODE pHead)//怎样遍历,是不能像以前一样用数组的,以为数组是连续的,这里不连续 95 { 96 PNODE p = pHead->pNext; 97 98 while (NULL != p) 99 { 100 printf("%d ", p->data); 101 p = p->pNext; 102 } 103 printf("\n"); 104 }
运行截图:
吟诗一首:
精神经百炼,锋锐坚不挫。 ——刘过
时间: 2024-09-30 17:13:15