标签:
我在之前一篇博客《C语言实现单链表(不带头结点)的基本操作》中具体实现了不带头结点的单链表的11种操作:如计算链表长度、初始化、创建链表、清空链表等等。但是在实际使用中,带头结点的单链表往往比不带头结点的单链表用的更多,使用也更为方便。因为不用单独考虑第一个节点的情况了,第一个节点和其他后续节点的处理全都一样了,简化操作。这篇博客将会来实现带头结点的单链表的11种操作。代码上传至: https://github.com/chenyufeng1991/LinkedList_HeadNode 。
(1)定义带头结点单链表的节点类型
typedef int elemType; typedef struct NodeList{ int element; struct NodeList *next; }Node;
//1.初始化带头结点的单链表 void InitialList(Node **pNode){ //个人建议每一次malloc分配内存空间后,都要进行判断分配是否成功,也即判断是否为空; //此时的这个pNode就是一个头结点; //初始化成功后,其实相当于是一个正常的链表了; *pNode = (Node *)malloc(sizeof(Node)); if (*pNode == NULL) { printf("%s函数执行,内存分配失败,初始化单链表失败",__FUNCTION__); }else{ (*pNode)->next = NULL; printf("%s函数执行,带头结点的单链表初始化完成\n",__FUNCTION__); } }
(3)尾插法创建带头结点的单链表
//2.创建带头结点的单链表 void CreateList(Node *pNode){ /** * 就算一开始输入的数字小于等于0,带头结点的单链表都是会创建成功的,只是这个单链表为空而已,也就是里面除了头结点就没有其他节点了。 */ Node *pInsert; Node *pMove; pInsert = (Node *)malloc(sizeof(Node));//需要检测分配内存是否成功 pInsert == NULL ? memset(pInsert, 0, sizeof(Node)); pInsert->next = NULL; scanf("%d",&(pInsert->element)); pMove = pNode; while (pInsert->element > 0) { pMove->next = pInsert; pMove = pInsert; pInsert = (Node *)malloc(sizeof(Node)); //需要检测分配内存是否成功 pInsert == NULL ? memset(pInsert, 0, sizeof(Node)); pInsert->next = NULL; scanf("%d",&(pInsert->element)); } printf("%s函数执行,带头结点的单链表创建成功\n",__FUNCTION__); }
(4)打印带头结点的单链表
//3.打印带头结点的单链表 void PrintList(Node *pNode){ /** * 注意这里,如果单链表为空(只有一个头结点),我也让它打印(打印成功)。只是里面没有元素,打出来是空的而已,所以在控制台上就是一行空的; */ Node *pMove; pMove = pNode->next; while (pMove != NULL) { printf("%d ",pMove->element); pMove = pMove->next; } printf("\n%s函数执行,打印带头结点的单链表成功\n",__FUNCTION__); }
//4.清除线性表中的所有元素,即释放所有节点(除了头结点),使之成为一个空表 void ClearList(Node *pNode){ Node *pMove; pMove = pNode->next; while (pMove != NULL) { pNode->next = pMove->next; free(pMove); pMove = pNode->next; } printf("%s函数执行,清空带头结点的链表成功\n",__FUNCTION__); }
//5.返回带头结点的单链表的长度 int SizeList(Node *pNode){ /** * 当只有一个头结点的时候,size = 0;头节点不计算到链表长度中。 */ int i = 0; Node *pMove; pMove = pNode->next; while (pMove != NULL) { i++; pMove = pMove->next; } printf("%s函数执行,带头结点的单链表的长度为:%d\n",__FUNCTION__,i); return i; }
//6.判断带头结点的单链表是否为空,为空则返回1,否则返回0 int IsEmptyList(Node *pNode){ /** * 当只有一个头结点的时候,该链表就为空 */ if (pNode->next == NULL) { printf("%s函数执行,带头结点的链表为空\n",__FUNCTION__); return 1; } printf("%s函数执行,带头结点的链表非空\n",__FUNCTION__); return 0; }
(8)查找链表某个位置元素
//7.返回单链表中第pos个结点中的元素,若返回-1,表示没有找到 int GetElement(Node *pNode,int pos){ int i = 1; Node *pMove; pMove = pNode->next; while (pMove != NULL) { if (i == pos) { printf("%s函数执行,pos=%d位置的值是%d\n",__FUNCTION__,pos,pMove->element); return pMove->element; } i++; pMove = pMove->next; } printf("%s函数执行,在pos=%d位置没有找到值\n",__FUNCTION__,pos); return -1; }
//8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL elemType* GetElemAddr(Node *pNode,int x){ Node *pMove; pMove = pNode->next; while (pMove != NULL) { if (pMove->element == x) { printf("%s函数执行,查找到x=%d的内存地址为:0x%x\n",__FUNCTION__,x,&(pMove->element)); return &(pMove->element); } pMove = pMove->next; } printf("%s函数执行,在带头结点的单链表中没有找到x=%d的值,无法获得内存地址\n",__FUNCTION__,x); return NULL; }
//9.把单链表中第pos个结点的值修改为x的值 Node* ModifyElem(Node *pNode,int pos,int x){ int i = 1; Node *pMove; pMove = pNode->next; while (pMove != NULL) { if (i == pos) { pMove->element = x; printf("%s函数执行,把pos=%d位置的值改为%d成功\n",__FUNCTION__,pos,x); return pNode; } i++; pMove = pMove->next; } printf("%s函数执行,链表为空或者输入pos值非法,修改值失败\n",__FUNCTION__); return pNode; }
//10.向单链表的表头插入一个元素 Node *InsertHeadList(Node *pNode,int x){ Node *pInsert; pInsert = (Node *)malloc(sizeof(Node)); memset(pInsert, 0, sizeof(Node)); pInsert->element = x; pInsert->next = pNode->next; pNode->next = pInsert; printf("%s函数执行,在表头插入元素%d成功\n",__FUNCTION__,x); return pNode; }
// 11.向单链表的末尾添加一个元素 Node *InsertTailList(Node *pNode,int x){ Node *pMove; Node *pInsert; pInsert = (Node *)malloc(sizeof(Node)); memset(pInsert, 0, sizeof(Node)); pInsert->element = x; pInsert->next = NULL; pMove = pNode; while (pMove->next != NULL) { pMove = pMove->next; } pMove->next = pInsert; printf("%s函数执行,在表尾插入元素%d成功\n",__FUNCTION__,x); return pNode; }
int main(int argc, const char * argv[]) { Node *pList; InitialList(&pList); CreateList(pList); PrintList(pList); SizeList(pList); IsEmptyList(pList); GetElement(pList, 3); GetElemAddr(pList, 5); ModifyElem(pList, 2, 111); PrintList(pList); InsertHeadList(pList,1234); PrintList(pList); SizeList(pList); InsertTailList(pList,9999); PrintList(pList); SizeList(pList); ClearList(pList); PrintList(pList); return 0; }
标签:
原文地址:http://blog.csdn.net/chenyufeng1991/article/details/50770891