赞
踩
双向链表的操作实现包括:初始化指针,打印链表,插入链表以及删除链表。
1、初始化结构体
实现的代码如下:
- #include <stdio.h>
- #include <malloc.h>
-
- //初始化结构体,一个是前驱指针,一个后继指针.
- typedef struct DoubleLinkedNode{
- char data;
- struct DoubleLinkedNode *previous;
- struct DoubleLinkedNode *next;
- } DLNode, *DLNodePtr;
-
- //初始化链表
- DLNodePtr initLinkList(){
- DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));//为dlnode申请一个大小为doublelinkednode指针大小的内存空间.
- tempHeader->data = '\0';
- tempHeader->previous = NULL;
- tempHeader->next = NULL;
- return tempHeader;
- }
2、打印链表
实现的代码如下:
- //打印链表函数
- void printList(DLNodePtr paraHeader){
- DLNodePtr p = paraHeader->next;
- while (p != NULL) {
- printf("%c", p->data);
- p = p->next;
- }
- printf("\r\n");
- }
3、实现插入
- //插入链表函数
- void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
- DLNodePtr p, q, r;
-
- // 第一步,查找位置,将指针p放到表头.
- p = paraHeader;
- for (int i = 0; i < paraPosition; i ++) {
- p = p->next;
- if (p == NULL) {
- printf("位置%d已经是最后一位了", paraPosition);
- return;
- }
- }
-
- //申请一块新的内存空间.
- q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
- q->data = paraChar;
-
- //开始插入新的链表.
- r = p->next;
- q->next = p->next;
- q->previous = p;
- p->next = q;
- if (r != NULL) {
- r->previous = q;
- }
- }
实现的代码如上:
4、删除函数
代码:
- //删除链表函数.
- void deleteElement(DLNodePtr paraHeader, char paraChar){
- DLNodePtr p, q, r;
- p = paraHeader;
-
- //锁定目标,必须是删除链表的前一个结点.
- while ((p->next != NULL) && (p->next->data != paraChar)){
- p = p->next;
- }
-
- //报错检查
- if (p->next == NULL) {
- printf("'%c'字符不存在\n", paraChar);
- return;
- }
-
- //删除链表
- q = p->next;
- r = q->next;
- p->next = r;
- if (r != NULL) {
- r->previous = p;
- }
-
- // 释放空间.
- free(q);
- }
完整代码如下:
- #include <stdio.h>
- #include <malloc.h>
-
- //初始化结构体,一个是前驱指针,一个后继指针.
- typedef struct DoubleLinkedNode{
- char data;
- struct DoubleLinkedNode *previous;
- struct DoubleLinkedNode *next;
- } DLNode, *DLNodePtr;
-
- //初始化链表
- DLNodePtr initLinkList(){
- DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));//为dlnode申请一个大小为doublelinkednode指针大小的内存空间.
- tempHeader->data = '\0';
- tempHeader->previous = NULL;
- tempHeader->next = NULL;
- return tempHeader;
- }
-
- //打印链表函数
- void printList(DLNodePtr paraHeader){
- DLNodePtr p = paraHeader->next;
- while (p != NULL) {
- printf("%c", p->data);
- p = p->next;
- }
- printf("\r\n");
- }
-
- //插入链表函数
- void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
- DLNodePtr p, q, r;
-
- // 第一步,查找位置,将指针p放到表头.
- p = paraHeader;
- for (int i = 0; i < paraPosition; i ++) {
- p = p->next;
- if (p == NULL) {
- printf("位置%d已经是最后一位了", paraPosition);
- return;
- }
- }
-
- //申请一块新的内存空间.
- q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
- q->data = paraChar;
-
- //开始插入新的链表.
- r = p->next;
- q->next = p->next;
- q->previous = p;
- p->next = q;
- if (r != NULL) {
- r->previous = q;
- }
- }
-
- //删除链表函数.
- void deleteElement(DLNodePtr paraHeader, char paraChar){
- DLNodePtr p, q, r;
- p = paraHeader;
-
- //锁定目标,必须是删除链表的前一个结点.
- while ((p->next != NULL) && (p->next->data != paraChar)){
- p = p->next;
- }
-
- //报错检查
- if (p->next == NULL) {
- printf("'%c'字符不存在\n", paraChar);
- return;
- }
-
- //删除链表
- q = p->next;
- r = q->next;
- p->next = r;
- if (r != NULL) {
- r->previous = p;
- }
-
- // 释放空间.
- free(q);
- }
-
- //插入删除测试函数
- void insertDeleteTest(){
- // 初始化一个空链表.
- DLNodePtr tempList = initLinkList();
- printList(tempList);
-
- //添加字符进行测试.
- insertElement(tempList, 'H', 0);
- insertElement(tempList, 'e', 1);
- insertElement(tempList, 'l', 2);
- insertElement(tempList, 'l', 3);
- insertElement(tempList, 'o', 4);
- insertElement(tempList, '!', 5);
- printList(tempList);
-
- //删除个别字符进行测试.
- deleteElement(tempList, 'e');
- deleteElement(tempList, 'a');
- deleteElement(tempList, 'o');
- printList(tempList);
-
- // 删除指定位置的字符.
- insertElement(tempList, 'o', 1);
- printList(tempList);
- }
-
- //设计打印存放字符地址的函数
- void basicAddressTest(){
- DLNode tempNode1, tempNode2;
-
- tempNode1.data = 4;
- tempNode1.next = NULL;
-
- tempNode2.data = 6;
- tempNode2.next = NULL;
-
- printf("第一个位置: %d, %d, %d\r\n",
- &tempNode1, &tempNode1.data, &tempNode1.next);
- printf("第二个位置: %d, %d, %d\r\n",
- &tempNode2, &tempNode2.data, &tempNode2.next);
-
- tempNode1.next = &tempNode2;
- }
-
-
- int main(){
- insertDeleteTest();
- basicAddressTest();
- }
运行结果:
总结:
双向链表是链表的一种,它和单向链表的区别是双向链表比单向链表每个节点多一个头指针,这个指针指向前一个节点,也就是说,每个节点包含包含头指针、存储元素、尾指针, 因此从这个节点可以同时访问到它前面和后面的节点。我们可以想一下,如果是单向链表,要访问一个节点前面的节点,就必须要从头结点开始遍历,直到找个这个节点前面的节点为止,而双向链表直接就可以访问前一个节点,查询和操作数据就会更加方便。这也是节省空间和时间的一种方式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。