精华内容
下载资源
问答
  • 实现双向链表删除一个指定元素。  4.在非递减有序双向链表中实现插入元素e仍有序算法。  5.判断双向链表中元素是否对称若对称返回1否则返回0。  6.设元素为正整型,实现算法把所有奇数排列在偶数之前。  ...
  • 双向链表,创建,插入,删除,销毁等,写的一个代码(包括详细的注释,初学者都看得懂),已经成功测试。及拿即用。
  • gcc doublist.c listMain.c -DDEBUG -o a.exe 调试输出 ************ testCreateDoubList ************ ========= Dump Double List 0x9ba010 =========== 22 32 19 53 0 47 29 116 4 6 ==================...

    代码实现

    st_doubNode * removeDoubListNode(st_doubNode** phead, int pos){
    	if(NULL == phead || pos < 0){
    		printf("%s: param error\n",__func__);
    		return NULL;
    	}
    
    	st_doubNode * head = *phead;
    	st_doubNode * p = NULL;
    	st_doubNode * q = NULL;
    	st_doubNode * nw = NULL;
    
    	if(0 == pos) { /*首节点*/
    		/*摘掉*/
    		nw = head;
    		p = head->next;
    		p->prev = NULL;
    
    		/*清除*/
    		nw->next = NULL;
    		nw->prev = NULL;
    
    		/*更新头*/
    		head = p;
    		
    	} else { /* 其他节点 */
    		nw = findDoubListPos(head, pos);
    		p = nw->next;
    		q = nw->prev;
    
    		p->prev = q;
    		q->next = p;
    
    		nw->next = NULL;		
    		nw->prev = NULL;
    	}
    
    	*phead = head;
    
    	return nw;
    }
    
    
    void testremoveDoubListNode(void){
    	st_doubNode * nw = NULL;
    
    	printf("\n************  testremoveDoubListNode ************ \n");
    	
    	nw = removeDoubListNode(&gDoubHead, 11);
    	if(NULL != nw)
    		printf("Removed node %p: data %d\n", nw, nw->data);
    	dumpDoubList(gDoubHead);
    	
    	nw = removeDoubListNode(&gDoubHead, 5);
    	if(NULL != nw)
    		printf("Removed node %p: data %d\n", nw, nw->data);
    	dumpDoubList(gDoubHead);
    	
    	nw = removeDoubListNode(&gDoubHead, 0);
    	if(NULL != nw)
    		printf("Removed node %p: data %d\n", nw, nw->data);	
    	dumpDoubList(gDoubHead);
    	dumpDoubListReverse(gDoubHead);
    
    	return;
    }
    
    

    代码编译

    gcc doublist.c listMain.c -DDEBUG -o a.exe

    调试输出

    ************  testCreateDoubList ************
    ========= Dump Double List 0x9ba010 ===========
             22  32  19  53  0  47  29  116  4  6
    ===================================
    ************  testCreateDoubList ************
    len  = 10
    
    
    ************  testremoveDoubListNode ************
    Removed node 0x9ba190: data 66
    ========= Dump Double List 0x9ba150 ===========
             70  22  32  19  53  31  0  47  29  116  4  6
    ===================================
    Removed node 0x9ba170: data 31
    ========= Dump Double List 0x9ba150 ===========
             70  22  32  19  53  0  47  29  116  4  6
    ===================================
    Removed node 0x9ba150: data 70
    ========= Dump Double List 0x9ba010 ===========
             22  32  19  53  0  47  29  116  4  6
    ===================================
    

     

    展开全文
  • 双链表删除节点

    千次阅读 2021-02-22 15:22:20
    编写一个程序,从双链表中移除一个节点,函数的原型如下 int dll_remove(struct NODE *rootp, struct NODE *node); 你可以假设节点数据结构在头文件double_linked_list_node.h文件中定义,函数第一个参数是一个...

    【12.8-6】编写一个程序,从双链表中移除一个节点,函数的原型如下

    int dll_remove(struct NODE *rootp, struct NODE *node);
    

    你可以假设节点数据结构在头文件double_linked_list_node.h文件中定义,函数第一个参数是一个指向包含链表根指针的节点的指针,第二个参数是个指向欲移除的节点的指针,如果链表并不包含欲移除的指针,函数就返回假,否则函数移除该节点并返回真。


    遇到链表操作的题目,第一步就是画一个链表图,然后理清指针指向然后再转化成代码

    删除一个节点的基本操作就是修改这个节点的上一个节点的fwd和下一个节点的bwd,如下删除中间节点示意:

    #define TRUE 1
    #define FALSE 0
    #define NUL '\0'
    
    typedef struct NODE {
        struct NODE *fwd;
        struct NODE *bwd;
        int value;
    } Node;
    
    
    int dll_remove(Node **rootp, Node *node) {
        if(node == NULL) {
            return FALSE;
        }
    
        Node *this;
        //寻找要删除的节点
        for (this = rootp->fwd; this != NULL; this = this->fwd) {
            if (this == node) {
                break;
            }
        }
    
        //如果找到要删除的节点
        if (this == node) {
            //修改前一个节点的fwd
            if(this->bwd == NULL) {
                rootp->fwd = this->fwd;
            } else {
                this->bwd->fwd = this->fwd;
            }
    
            //修改后一个节点的bwd
            if(this->fwd == NULL) {
                rootp->bwd = this->bwd;
            } else {
                this->fwd->bwd = this->bwd;
            }
            free(this);
            return TRUE;
        }
        return FALSE;
    }

    注意:遇到双链表的操作,一定要注意处理头部节点和尾节点。

    展开全文
  • 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表...
  • 数据结构---线性表之双链表,创建、插入、删除,完整的C代码
  • C语言双向链表讲解

    千次阅读 2020-04-14 11:53:37
    双链表添加了一个指针域,通过两个指针域,分别指向结点的前结点和后结点。这样的话,可以通过双链表的任何结点,访问到它的前结点和后结点。 在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接...

    lfylcj

    C语言双向链表讲解

     

     

     

    上图对应如下代码:

    pnode->prev = pindex->prev;
     pnode->pNext = pindex;
     pindex->prev->pNext = pnode;
     pindex->prev = pnode;

     

     

    上图对应如下代码:

    pnode->prev = phead;

    pnode->pNext = phead->pNext;

    phead->pNext->prev = pnode;

    phead->pNext = pnode;

     

    上图对应如下代码:

    pnode->pNext = phead;

     pnode->prev = phead->prev;

     phead->prev->pNext = pnode;

     phead->prev = pnode;

     

     

    上图对应如下代码:

    pindex->pNext->prev = pindex->prev;

    pindex->prev->pNext = pindex->pNext;

     

    一、双向链表的概念

        双向链表基于单链表。单链表是单向的,有一个头结点,一个尾结点,要访问任何结点,都必须知道头结点,不能逆着进行。而双链表添加了一个指针域,通过两个指针域,分别指向结点的前结点和后结点。这样的话,可以通过双链表的任何结点,访问到它的前结点和后结点。

        在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点的地址,一般称为右链域;一个存储直接前驱结点地址,一般称之为左链域。

        双向链表结构示意图

        

    表头为空,表头的后继节点为"节点10"(数据为10的节点);"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的前继节点是"节点10";"节点20"的后继节点是"节点30","节点30"的前继节点是"节点20";...;末尾节点的后继节点是表头。

    双链表删除节点

    删除"节点30"
    删除之前:"节点20"的后继节点为"节点30","节点30" 的前继节点为"节点20"。"节点30"的后继节点为"节点40","节点40" 的前继节点为"节点30"。
    删除之后:"节点20"的后继节点为"节点40","节点40" 的前继节点为"节点20"。

     

    双链表添加节点

    在"节点10"与"节点20"之间添加"节点15"
    添加之前:"节点10"的后继节点为"节点20","节点20" 的前继节点为"节点10"。
    添加之后:"节点10"的后继节点为"节点15","节点15" 的前继节点为"节点10"。"节点15"的后继节点为"节点20","节点20" 的前继节点为"节点15"。

    二、C语言实现双向链表

    2.1 头文件

    复制代码

     1 #pragma once
     2 //新建双向链表。成功返回链表头,否则,返回NULL
     3 extern int create_dLink();
     4 //撤销双向链表,成功返回0,否则返回-1
     5 extern int destory_dLink();
     6 //双向列表是否为空,为空返回1,否则返回0
     7 extern int  is_empty_dLink();
     8 //双向链表的大小
     9 extern int dLink_size();
    10 //获取索引index位置的元素,成功返回节点指针,否则返回NULL
    11 extern  void* dLink_get(int index);
    12 //获取双向链表中第一个元素,成功返回节点指针,否则返回NULL
    13 extern void* dLink_getFirst();
    14 //获取双向链表中最后一个元素,成功返回节点指针,否则返回NULL
    15 extern void* dLink_getTail();
    16 /*
    17 链表中增加
    18 */
    19 //在Index位置插值value,成功返回0,否则返回-1;
    20 extern int dLink_insert(int index,void * pVal);
    21 //在表头插入值
    22 extern int dLink_insert_head(void *pVal);
    23 //在表尾插入值
    24 extern int dLink_insert_tail(void *pVal);
    25 /*
    26 链表中删除
    27 */
    28 //在index处删除
    29 extern int  dLink_delete(int index);
    30 //删除第一个节点
    31 extern int dLink_delete_first();
    32 //闪电湖第二个节点
    33 extern int dLink_delete_tail();

    复制代码

    2.2 .c

    复制代码

      1 #include<stdio.h>
      2 #include "double_link.h"
      3 #include<malloc.h>
      4 
      5 //双向链表节点
      6 typedef struct My_node
      7 {
      8     struct My_node *prev;
      9     struct  My_node *pNext;
     10     void * p;
     11 }my_node;
     12 //b表头不存放元素值
     13 my_node *phead = NULL;
     14 //节点的个数
     15 int node_count = 0;
     16 //创建节点,成功返回节点指针,否则,返回NULL
     17 my_node* create_node(void *pVal)
     18 {
     19     my_node *pnode = NULL;
     20     pnode = (my_node*)malloc(sizeof(My_node));
     21     if (!pnode)
     22     {
     23         printf("create pnode error\n");
     24         return NULL;
     25     }
     26     //默认的,pnode的前一节点和后一节点都指向他自己
     27     pnode->prev  = pnode->pNext = pnode;
     28     //节点的值为pVal
     29     pnode->p = pVal;
     30     return pnode;
     31 }
     32 
     33 //新建双向链表 成功返回0 否则返回-1
     34 int create_dLink()
     35 {
     36     phead = create_node(NULL);
     37     if (!phead)
     38         return -1;
     39     //设置节点的个数
     40     node_count = 0;
     41     return 0;
     42 }
     43 
     44 int destory_dLink()
     45 {
     46     if (!phead)
     47     {
     48         printf("%s failed! dlink is null!\n", __func__);
     49          return -1;
     50     }
     51     My_node*pnode = phead->pNext;
     52     my_node* ptmp = NULL;
     53     if (pnode!=phead)
     54     {
     55         ptmp = pnode;
     56         pnode = pnode->pNext;
     57         free(pnode);
     58     }
     59     free(phead);
     60     phead = NULL;
     61     node_count = 0;
     62     return 0;
     63 }
     64 
     65 int is_empty_dLink()
     66 {
     67     return node_count==0;
     68 }
     69 
     70 int dLink_size()
     71 {
     72     return node_count;
     73 }
    
     74 //获取双向链表中第Index位置的节点
     75 my_node* get_node(int index)
     76 {
     77     if (index<0 || index >= node_count)
     78     {
     79         printf("%s failed ! index out of bound\n", __func__);
     80         return NULL;
     81     }
     82     //正向查找
     83     if (index <= (node_count / 2))
     84     {
     85         int i = 0;
     86         my_node *pnode = phead->pNext;
     87         while ((i++)<index)
     88         {
     89             pnode = pnode->pNext;
     90         }
     91         return pnode;
     92     }
     93     //反向查找
     94     int j = 0;
     95     int rindex = node_count - index - 1;
     96     my_node *rnode = phead->prev;
     97     while ((j++)<rindex)
     98     {
     99         rnode = rnode->prev;
    100     }
    101     return rnode;
    102 }
    103 void * dLink_get(int index)
    104 {
    105     my_node *pindex = get_node(index);
    106     if (!pindex)
    107     {
    108         printf("%s failed!\n", __func__);
    109         return NULL;
    110     }
    111     return pindex->p;
    112 }
    113 
    114 //获取第一个节点
    115 void * dLink_getFirst()
    116 {
    117     return get_node(0) ;
    118 }
    119 //获取最后一个节点
    120 void * dLink_getTail()
    121 {
    122     return get_node(node_count-1);
    123 }
    
    124 //将值插入到index位置,成功返回0;否则 返回-1
    125 int dLink_insert(int index, void * pVal)
    126 {
    127     //插入表头
    128     if (index == 0)
    129         return dLink_insert_head(pVal);
    130     //获取要插入位置对应的节点
    131     my_node* pindex = get_node(index);
    132     if (!pindex)
    133         return -1;
    134     //创建节点
    135     my_node* pnode = create_node(pVal);
    136     if (!pnode)
    137         return -1;
    138     pnode->prev = pindex->prev;
    139     pnode->pNext = pindex;
    140     pindex->prev->pNext = pnode;
    141     pindex->prev = pnode;
    142     node_count++;
    143     return 0;
    144 }
    145 //数值插入表头
    146 int dLink_insert_head(void * pVal)
    147 {
    148     my_node* pnode = create_node(pVal);
    149     if (!pnode)
    150         return -1;
    151     pnode->prev = phead;
    152     pnode->pNext = phead->pNext;
    153     
    154     phead->pNext->prev = pnode;
    155     phead->pNext = pnode;
    156     node_count++;
    157     return 0;
    158 }
    159 
    160 int dLink_insert_tail(void * pVal)
    161 {
    162     my_node* pnode = create_node(pVal);
    163     if (!pnode)
    164         return -1;
    165     pnode->pNext = phead;
    166     pnode->prev = phead->prev;
    167     phead->prev->pNext = pnode;
    168     phead->prev = pnode;
    169     return 0;
    170 }
    171 
    172 int dLink_delete(int index)
    173 {
    174     my_node* pindex = get_node(index);
    175     if (!pindex)
    176     {
    177         printf("%s failed! the index in out of bound\n",__func__);
    178         return -1;
    179     }
    180     pindex->pNext->prev = pindex->prev;
    181     pindex->prev->pNext = pindex->pNext;
    182     free(pindex);
    183     node_count--;
    184     return 0;
    185 }
    186 
    187 int dLink_delete_first()
    188 {
    189     return dLink_delete(0);
    190 }
    191 
    192 int dLink_delete_tail()
    193 {
    194     return dLink_delete(node_count-1);
    195 }

    复制代码

    2.3 test测试代码

    复制代码

     1 #include<stdio.h>
     2 #include"double_link.h"
     3 //1.双向链表操作数为int
     4 void int_test()
     5 {
     6     int arr[10] = {11,55,67,90,21,45,23,59,79,10};
     7     printf("xxxxxxxxxxxxxxxxx\n");
     8     create_dLink();                    //创建链表
     9     dLink_insert(0, &arr[0]);        //双向链表表头插入
    10     dLink_insert(0, &arr[1]);        //双向链表表头插入
    11     dLink_insert(0, &arr[2]);        //双向链表表头插入
    12     dLink_insert(0, &arr[3]);        //双向链表表头插入
    13     dLink_insert(0, &arr[4]);        //双向链表表头插入
    14     dLink_insert(0, &arr[5]);        //双向链表表头插入
    15     printf("is_empty_dLink()=%d\n",is_empty_dLink());    //双向链表是否为空
    16     printf("dLink_size()=%d\n", dLink_size());                    //双向链表的大小
    17     //遍历双向链表
    18     int i ;
    19     int * p ;
    20     int sz = dLink_size();
    21     for ( i = 0; i < sz; i++)
    22     {
    23         p = (int*)dLink_get(i);
    24         printf("dLink_get(%d)=%d\n",i,*p);
    25     }
    26     destory_dLink();
    27 }
    28 
    29 //2.操作数为字符串
    30 void string_test()
    31 {
    32     char* str[] = {"one","two","three","four","five"};
    33     create_dLink();                    //创建链表
    34     dLink_insert(0, str[0]);        //双向链表表头插入
    35     dLink_insert(0, str[1]);        //双向链表表头插入
    36     dLink_insert(0, str[2]);        //双向链表表头插入
    37     printf("is_empty_dLink()=%d\n", is_empty_dLink());    //双向链表是否为空
    38     printf("dLink_size()=%d\n", dLink_size());                    //双向链表的大小
    39                                                                 //遍历双向链表
    40     int i ;
    41     char * p ;
    42     int sz = dLink_size();
    43     for (i = 0; i < sz; i++)
    44     {
    45         p = (char*)dLink_get(i);
    46         printf("dLink_get(%d)=%s\n", i, p);
    47     }
    48     destory_dLink();
    49 }
    50 //3.双向链表为结构体
    51 typedef struct MyStruct
    52 {
    53     int id;
    54     char name[20];
    55 } stu;
    56 stu arr_stu[] =
    57 {
    58     {1000,"lii"},
    59     { 1001,"mike" },
    60     { 1002,"lucky" },
    61     { 1003,"eric" },
    62 };
    63 #define arr_stu_size  ((sizeof(arr_stu))/(sizeof(arr_stu[0])))
    64 void stuc_test()
    65 {
    66     create_dLink();                    //创建链表
    67     dLink_insert(0, &arr_stu[0]);        //双向链表表头插入
    68     dLink_insert(0, &arr_stu[1]);        //双向链表表头插入
    69     dLink_insert(0, &arr_stu[2]);        //双向链表表头插入
    70     printf("is_empty_dLink()=%d\n", is_empty_dLink());    //双向链表是否为空
    71     printf("dLink_size()=%d\n", dLink_size());                    //双向链表的大小
    72                                                                 //遍历双向链表
    73     int i ;
    74     stu * p ;
    75     int sz = dLink_size();
    76     for (i = 0; i < sz; i++)
    77     {
    78         p = (stu*)dLink_get(i);
    79         printf("dLink_get(%d)=[%d,%s]\n", i, p->id,p->name);
    80     }
    81     destory_dLink();
    82 }
    83 int main()
    84 {
    85     int_test();
    86     string_test();
    87     stuc_test();
    88     
    89     return 0;
    90 }

    复制代码

    2.34结果显示

    展开全文
  • C语言实现双向链表

    2020-09-03 21:17:01
    本文给大家分享的是一段使用C语言实现双向链表的代码,完全是根据自己的理解和认识来编写的,希望大家能够喜欢,文章的最后附上了一个网友写的对于双向链表删除节点、插入节点、双向输出等操作的代码,也非常不错,...
  • 这是一个关于双链表的创建,删除,插入操作
  • 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表...
  • 最近学习C语言链表操作,看了很多例子,学习完成后我自己总结了一下,并写了比较完整的代码。下面是我写的代码,代码的量可能有点大,请谅解。如果有错误或者不合适之处请指出。我用的开发环境是windows的VS。 ...
    		最近学习C语言的链表操作,看了很多例子,学习完成后我自己总结了一下,并写了比较完整的代码。下面是我写的代码,代码的量可能有点大,请谅解。如果有错误或者不合适之处请指出。我用的开发环境是windows的VS。
    		在该代码中主要的内容有
    		** 
    		1 链表的创建。创建方法有头插法和尾插法
    		2 链表的增添。
    		3 链表的删除。包括两种情况,分为删除指定的位置节点和删除指定数据所在的节点
    		4 链表的修稿。包括两种情况,分为修改指定的位置节点和修改指定数据所在的节点
    		5 链表的释放。释放方法有两种,分为从头部释放和从尾部释放
    		**
    
    #include "stdafx.h"
    #include<stdbool.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<stdarg.h>
    #define SIZE 20
    typedef struct mydata
    {
    	char *str = (char *)malloc(sizeof(char) * 20);
    	struct mydata *forward = NULL;
    	struct mydata *backward = NULL;
    }Node,*Mydata;
    char *GetInput(char *str);
    int Initializ(Mydata *head);
    int CreatFromHead(Mydata head);
    int OutPutLinkedListInforward(Mydata head);
    int OutPutLinkedListFromBackward(Mydata head);
    int AddAccordingToLocation(Mydata head,unsigned int location, char *str);//在指定的位置增加节点(前插)
    int AddAccordingToLocationUseAfter(Mydata head,unsigned int location, char *str);
    int DeletAccordingToLocation(Mydata head,unsigned int location);
    int DeletAccordingToStr(Mydata head, char *str);
    int ModificationAccordingToLocation(Mydata head,unsigned int location, char *str);
    int ModificationAccordingToStr(Mydata head, char *str,char *replacestr);
    int FreeFromBackward(Mydata head);
    int main()
    {
    	Mydata head;
    	int location = 1;
    	Initializ(&head);//初始化表头
    	CreatFromHead(head);//创建链表
    	OutPutLinkedListInforward(head);//输出最原始的链表(从前输出)
    	OutPutLinkedListFromBackward(head);//输出最原始的链表(从后输出)
    	AddAccordingToLocation(head, 1, "adcdefg");//在指定位置添加数据(前插)
    	puts("After add one node is:");
    	OutPutLinkedListInforward(head);//输出修改后的链表
    	AddAccordingToLocationUseAfter(head,1, "110");//在指定位置添加数据(后插)
    	puts("After add one node is:");
    	OutPutLinkedListInforward(head);//输出修改后的链表
    	puts("enter the location that you want to delet:");
    	scanf_s("%d", &location);
    	DeletAccordingToLocation(head, location);//删除指定位置的数据
    	puts("after deleting one node is:");
    	OutPutLinkedListInforward(head);//输出修改后的链表
    	puts("enter the string that you want to delet:");
    	getchar();
    	char *str1 = (char *)malloc(sizeof(char)*SIZE);
    	GetInput(str1);
    	DeletAccordingToStr(head,str1);//删除指定数据所在的节点
    	puts("After delete one node is:");
    	OutPutLinkedListInforward(head);//输出修改后的链表
    	puts("enter the location that you want to modification:");
    	scanf_s("%d", &location);
    	ModificationAccordingToLocation(head, location, "119");//修改指定位置的节点的数据为指定的数据
    	puts("After modificationing one node is:");
    	OutPutLinkedListInforward(head);//输出修改后的链表
    	puts("enter the str that you want to modification:");
    	getchar();
    	char *str2 = (char *)malloc(sizeof(char)*SIZE);
    	GetInput(str2);
    	puts("enter the new str that you want to interposition:");
    	char *str = (char *)malloc(sizeof(char)*SIZE);
    	GetInput(str);
    	ModificationAccordingToStr(head, str2,str);//修改指定数据所在的节点的数据为指定的数据
    	puts("After modificationing one node is:");
    	OutPutLinkedListInforward(head);//输出修改后的链表
    	FreeFromBackward(head);
    	system("pause");
        return 0;
    }
    char *GetInput(char *str)//得到所需的字符串
    {
    	char *find;
    	char *start = fgets(str, SIZE, stdin);
    	if (start)
    	{
    		find = strchr(start, '\n');
    		if (find)
    			*find = '\0';
    		else
    			while (getchar() != '\n');
    	}
    	return start;
    
    }
    int Initializ(Mydata *head)//初始化表头
    {
    	(*head) = (Mydata)malloc(sizeof(Node));
    	if ((*head) == NULL)
    		return 0;
    	else
    	{
    		(*head)->forward = NULL;
    		(*head)->backward = NULL;
    		return 1;
    	}
    }
    int CreatFromHead(Mydata head)//创建链表(头插法)
    {
    	if (head == NULL)
    	{
    		puts("there is no header.");
    		return 0;
    	}
    	else
    	{
    		puts("Please enter one number to start:(enter \"Q\" to quit)");
    		while (getchar()!='Q')
    		{
    			while (getchar() != '\n');
    			Mydata now = (Mydata)malloc(sizeof(Node));
    			if (now == NULL)
    			{
    				puts("mamery allocation failed.");
    				return 0;
    			}
    			else
    			{
    				puts("Please enter one string:");
    				char *str = (char *)malloc(sizeof(char)*SIZE);//创建新的节点
    				now->str = GetInput(str);
    				now->forward = head->forward;
    				if (head->backward == NULL)//将头节点的backward指向最后一个节点
    				{
    					head->backward = now;
    					now->forward = NULL;
    				}
    				if (head->forward != NULL)//如果链表不是空的将上个节点的backward指向新的节点
    					head->forward->backward = now;
    				head->forward = now;
    				now->backward = head;
    				puts("Please enter one number to continue:(enter \"Q\" to quit)");
    			}
    		}
    		return 1;
    	}
    }
    int CreatFromTail(Mydata tail)//创建链表(尾插法)
    {
    	Mydata replace = tail;
    	puts("Please enter one number to start:(enter \"Q\" to quit)");
    	while (getchar() != 'Q')
    	{
    		while (getchar() != '\n');
    		Mydata now = (Mydata)malloc(sizeof(Node));
    		if (now == NULL)
    			return 0;
    		else
    		{
    			puts("Please enter  one string :");
    			char *str = (char *)malloc(sizeof(char) * 20);
    			now->str = GetInput(str);
    			replace->forward = now;
    			now->backward = replace;
    			now->forward = NULL;
    			replace = now;
    			puts("Please enter one number to contnue:");
    		}
    		
    	}
    	tail->backward = replace;
    	return 1;
    }
    int OutPutLinkedListInforward(Mydata head)//从头部进行输出
    {
    	Mydata replace = head->forward;
    	int location = 1;
    	if (replace == NULL)
    	{
    		puts("there is nothing.");
    		return 0;
    	}
    	else
    	{
    		puts("Output according to from forward to backward is:");
    		while (true)
    		{
    			printf("the %-2d is %s\n", location, replace->str);
    			replace = replace->forward;
    			if (replace == NULL)
    				break;
    			location++;
    		}
    	}
    	return location;
    }
    int OutPutLinkedListFromBackward(Mydata head)//从尾部进行输出
    {
    	Mydata  replace = head->backward;
    	int location = 1;
    	if (replace == NULL)
    		return 0;
    	else
    	{
    		puts("Output according from backward to forward is:");
    		while (true)
    		{
    			printf("the %-2d is %s\n", location, replace->str);
    			replace = replace->backward;
    			if (replace == head)//如果当前节点和头节点相同,跳出循环,结束
    				break;
    			location++;
    		}
    	}
    	return 1;
    }
    int AmountOfNode(Mydata head)//计算链表中节点的个数
    {
    	Mydata replace = head->forward;
    	if (replace == NULL || head == NULL)
    		return 0;
    	else
    	{
    		int amount = 1;
    		while (true)
    		{
    			replace = replace->forward;
    			if (replace == NULL)
    				break;
    			amount++;
    		}
    		return amount;
    	}
    }
    int FreeFromBackward(Mydata head)//从尾部进行资源释放
    {
    	Mydata replace;
    	Mydata replaceHead = head;
    	if (head == NULL)
    		return 0;
    	else
    	{
    		head = head->backward;
    		while (true)
    		{
    			replace = head;
    			head = head->backward;
    			free(replace);
    			if (head == replaceHead)//如果当前节点和头节点相同,跳出循环,结束
    				break;
    		}
    	}
    	return 1;
    }
    int AddAccordingToLocation(Mydata head,unsigned int location,char *str)//在指定的位置增加节点(前插)
    {
    	if (location == 0)
    	{
    		puts("enter location(location must greater then 0) is error.");
    		return 0;
    	}
    	else
    	{
    		Mydata replace = head->forward;
    		if (head == NULL)
    		{
    			puts("there is no header.");
    			return 0;
    		}
    		else
    		{
    			if (location > AmountOfNode(head) + 1)//允许插入链表的末尾
    			{
    				puts("location out of range");
    				return 0;
    			}
    			else
    			{
    				int i = 1;
    				Mydata previous = NULL;
    				while (i++ != location)//找到目标节点,之后在该节点的前面插入新的节点
    				{
    					previous = replace;
    					replace = replace->forward;
    				}
    				Mydata now = (Mydata)malloc(sizeof(Node));
    				if (now == NULL)//如果内存分配失败,结束
    				{
    					puts("Memory allocation failed.");
    					return 0;
    				}
    				else
    				{
    
    					now->str = str;						//前插法
    					now->forward = replace;
    					if (replace != NULL)
    					{
    						now->backward = replace->backward;
    						replace->backward->forward = now;
    						replace->backward = now;
    					}
    					else
    					{
    						head->backward = now;
    						now->backward = previous;
    						previous->forward = now;
    					}
    					return 1;
    				}
    			}
    		}
    	}
    }
    int AddAccordingToLocationUseAfter(Mydata head,unsigned int location, char *str)//在指定的位置增加节点(后插)
    {
    	if (location == 0)
    	{
    		puts("enter location(location must greater then 0) is error.");
    		return 0;
    	}
    	else
    	{
    		Mydata replace = head;
    		if (head == NULL)
    		{
    			puts("there is no header.");
    			return 0;
    		}
    		else
    		{
    			if (location > AmountOfNode(head) + 1)//同样允许在链表的末尾插入节点
    			{
    				puts("location out of range");
    				return 0;
    			}
    			else
    			{
    				int i = 0;
    				while (i++<location - 1)//找到目标节点的前一个节点
    					replace = replace->forward;
    				Mydata now = (Mydata)malloc(sizeof(Node));
    				if (now == NULL)
    				{
    					puts("Memory allocation failed.");
    					return 0;
    				}
    				else
    				{
    					now->str = str;
    					now->backward = replace;
    					now->forward = replace->forward;
    					if (replace->forward != NULL)
    						replace->forward->backward = now;
    					else
    						head->backward = now;
    					replace->forward = now;
    					return 1;
    				}
    			}
    		}
    	}
    }
    int DeletAccordingToLocation(Mydata head,unsigned int location)//在指定的位置删除节点
    {
    	if (location == 0)
    	{
    		puts("enter location(location must greater then 0) is error.");
    		return 0;
    	}
    	else
    	{
    		Mydata replace = head;
    		if (replace == NULL)
    		{
    			puts("the Linked list is NULL.");
    			return 0;
    		}
    		else
    		{
    			if (location>AmountOfNode(head))
    			{
    				puts("location out of range.");
    				return 0;
    			}
    			int i = 0;
    			while (i++ != location)//找到目标节点
    			{
    				replace = replace->forward;
    			}
    			replace->backward->forward = replace->forward;
    			if (replace->forward != NULL)
    				replace->forward->backward = replace->backward;
    			else
    			{
    				head->backward = replace->backward;
    			}
    			if (head->backward == head)
    			{
    				puts("now the Linked list is NULL.");
    				head->forward = NULL;
    				head->backward = NULL;
    			}
    			free(replace);
    			return 1;
    		}
    	}
    }
    int DeletAccordingToStr(Mydata head, char *str)//删除指定数据所在的节点
    {
    	Mydata replace = head->forward;
    	if (replace == NULL)
    	{
    		puts("the Linked list is NULL.");
    		return 0;
    	}
    	else
    	{
    		while (true)
    		{
    			if (replace==NULL || strcmp(replace->str, str) == 0)//找到目标数据或者循环到链表结尾
    				break;
    			replace = replace->forward;
    		}
    		if (replace == NULL)//如果没找到 ,退出,结束
    		{
    			puts("no one is mathing.");
    			return 0;
    		}
    		else//如果找到目标字符串
    		{
    			replace->backward->forward = replace->forward;
    			if (replace->forward != NULL)
    				replace->forward->backward = replace->backward;
    			else
    			{
    				head->backward = replace->backward;
    			}
    			if (head->forward == head)//如果删除后链表是空的,将表头重新初始化
    			{
    				puts("now the Linked list is NULL.");
    				head->forward = NULL;
    				head->backward = NULL;
    			}
    			free(replace);
    			return 1;
    		}
    	}
    }
    int ModificationAccordingToLocation(Mydata head,unsigned int location, char *str)//修改指定位置的节点的数据
    {
    	if (location == 0)
    	{
    		puts("enter location(location must greater then 0) is error.");
    		return 0;
    	}
    	else
    	{
    		Mydata replace = head->forward;
    		if (replace == NULL)
    		{
    			puts("the Linked list is NULL.");
    			return 0;
    		}
    		else
    		{
    			if (location > AmountOfNode(head))
    			{
    				puts("location out of range.");
    				return 0;
    			}
    			else
    			{
    				int i = 1;
    				while (i++ < location)//找到目标节点
    				{
    					replace = replace->forward;
    				}
    				replace->str = str;//修改数据为指定数据
    				return 1;
    			}			
    		}
    	}
    }
    int ModificationAccordingToStr(Mydata head, char *str,char *replacestr)//修改指定数据的节点的数据
    {
    
    	Mydata replace = head->forward;
    	if (replace == NULL)
    	{
    		puts("the Linked list is NULL.");
    		return 0;
    	}
    	else
    	{
    		while (true)
    		{
    			if ( replace==NULL|| strcmp(replace->str, str) == 0)
    				break;
    			replace = replace->forward;
    		}
    		if (replace == NULL)
    		{
    			puts("no one is maching.");
    			return 0;
    		}
    		else
    		{
    			replace->str = replacestr;
    			return 1;
    		}
    	}
    }
    
    以上就是我的代码,代码量比较大 ,但是使用起来比较对用户比较友好。
    
    展开全文
  • 实现通用的双向链表c语言实现)

    千次阅读 2017-10-16 15:46:08
    从实现一个通用的双向链表开始。 1. 构建链表节点   链表节点存值还是存值的地址(指针)?对于通用链表首先要做到能够存放任何数据类型的数据,首先可能会想到的是union,但是数据类型无穷无尽,不可能在union...
  • 双向链表的尾插法同单链表的尾插法一样,通过将新结点逐个插入链表的尾部来创建链表,将链表尾部的结点的指针域指向后缀,不同的是新结点不仅需要将链表尾部结点的后缀指针域指向新结点,还需要将新结点的前缀指向...
  • c语言实现双向链表

    千次阅读 2018-09-05 13:42:13
    双链表操作 开发环境codeblocks12.11 xxwu */ #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;stdbool.h&gt; typedef int ElemType; typedef struct DNode{  ...
  • 双向链表C语言实现

    2018-12-13 13:36:34
    通过双向链表实现按照ID序列插入,可以排序实现插入、删除、更新、修改;
  • 双链表详解(C语言版)

    千次阅读 多人点赞 2020-10-16 23:02:53
    在单链表中,因为每个结点包含下一个结点的地址,但是没有其先前结点的任何记录,所以造成单链表只能在一个方向上遍历,这就需要我们寻找另一种数据结构来克服单链表的这一缺点,这种结构就是双链表
  • else//没有找到合适的位置,只有将数据插入到链表尾部 { p->next = temp; //遍历到链表尾部,p==NULL temp ->pre = p; temp ->next = NULL; return head; } } int main() { DlinkedList_Node *head; head =...
  • 而双向链表结点中有两个指针,分别指向其前驱结点和后继结点,这样就可以实现链表的双向遍历了。 2.双向链表的具体实现过程 #include<stdio.h> #include<malloc.h> #define ElemType int typedef ...
  • 数据结构之C语言实现双向链表

    千次阅读 多人点赞 2018-07-07 12:17:29
    C语言实现双向链表 双向链表主要实现以下功能: 双向链表创建 节点头插 节点尾插 指定位置插入节点 节点删除 链表排序 链表求长 /********************************************************************...
  • 循环双向链表,实现了插入、查找特定的节点、删除等功能,是自己花了半天的时间写完的。
  • 目录 二、双向链表增删改查函数声明 ...五、节点删除 六、链表清空 七、链表销毁 八、验证程序 一、双向链表数据结构 struct double_list_node { struct double_list_node *prev; /* pr...
  • 第二,大家在很多书上看到的是使用单链表实现队列,我这里将会使用带头结点尾结点的非循环双链表实现,虽然多维护了两个节点和指针域,但是在链表头尾进行插入删除的时候不需要遍历链表了,队列操作变得非常
  • C语言双链表

    2019-04-01 13:27:22
    二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针...C语言双链表,可以增加。插入,删除,修改,销毁等函数接口。
  • 双链表删除节点操作)

    千次阅读 2020-12-10 20:54:32
    双链表删除第i个节点算法如下: 首先要会: 双链表的存储结构定义: typedef struct DLinkList{ int data; DLinkList * prior; DLinkList * next; }DLinkList; 思路: 假设删除双链表L中*p 节点 , 的 后继...
  • 建立双向链表,将它作为一个...从键盘输入命令字符,可以对缓冲区buffer中的文本进行定位,查找,替换,删除某行,添加某行等操作。编译环境VC6.0。fflush在VC6.0下可以正确工作,在其它编译环境下可能无法正常执行。
  • 看: #include #include typedef int ... } 注意:双链表的插入(头插和尾插)操作中无需判断链表是否为空(即除了头节点外是否存在结点),这一特点使得其插入操作变得简单许多; 具体原因就看着代码捋一遍就明白了;
  • 链表是一种最普遍的数据组织方式,他不需要连续的大片内存也可以存储大量的数据,而且对于数据的插入和删除运算响应速度也够快,但是查找性能一般。 红黑树是一种更加高大上的数据组织方式,他虽然逻辑稍显复杂,但...
  • 双向链表的几种插入,删除,指定位置输出 双向链表的长相 双向链表由前驱指针和后项指针还有数据域组成,把节点之间的前后指针相连接形成链表 双向链表节点的封装 双向链表与单链表相比,仅多了一个前驱指针 ...
  • 熟悉C++的STL(标准模板库)的人都知道list底层是一个双向链表,支持通用类型数据的存储,使用起来非常方便,但对于C语言开发者来说,并没有这么方便的工具,所以在这里记录一下自己实现的通用数据类型双向链表,提供...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,141
精华内容 31,256
关键字:

双链表的删除c