C 算法精介----链表->循环链表

 前面对单链表和双链表的定义和抽象数据类型进行简单的介绍。下面介绍另外一种链表,循环链表。他提供了一种更灵活的遍历链表元素的能力,循环链表可以是单向的也可以是双向的。区分链表是循环链表的主要看他最后一个元素的next指针是不是指向的头元素(或者说 :如果一个链表没有尾部元素则是循环链表)。下面是以单向链表来介绍。

<p class="p1"><span class="s1">//</span></p><p class="p1"><span class="s1">//  Clist.c</span></p><p class="p1"><span class="s1">//  Algorithms&Data_structures</span></p><p class="p1"><span class="s1">//</span></p><p class="p1"><span class="s1">//  Created by TTc on 15-2-2.</span></p><p class="p1"><span class="s1">//  Copyright (c) 2015</span><span class="s2">年</span><span class="s1"> TTc. All rights reserved.</span></p><p class="p1"><span class="s1">//</span></p><p class="p2"><span class="s1"></span>
</p><p class="p3"><span class="s1">#include </span><span class="s3">"Clist.h"</span></p><p class="p3"><span class="s1">#include </span><span class="s3"><stdio.h></span></p><p class="p4"><span class="s4">#include </span><span class="s1"><string.h></span></p><p class="p2"><span class="s1"></span>
</p><p class="p1"><span class="s1">//O(1)</span></p><p class="p3"><span class="s1">void</span></p><p class="p5"><span class="s1">clist_init(</span><span class="s5">CList</span><span class="s1"> *clist, </span><span class="s4">void</span><span class="s1"> (*destroy)(</span><span class="s4">void</span><span class="s1"> *data)){</span></p><p class="p5"><span class="s1">    clist-></span><span class="s5">size</span><span class="s1"> = 0;</span></p><p class="p5"><span class="s1">    clist-></span><span class="s5">destroy</span><span class="s1"> = destroy;</span></p><p class="p5"><span class="s1">    clist-></span><span class="s5">head</span><span class="s1"> = </span><span class="s4">NULL</span><span class="s1">;</span></p><p class="p5"><span class="s1">}</span></p><p class="p1"><span class="s1">//O(n)</span></p><p class="p3"><span class="s1">void</span></p><p class="p5"><span class="s1">clist_destroy(</span><span class="s5">CList</span><span class="s1"> *clist){</span></p><p class="p5"><span class="s1">    </span><span class="s4">void</span><span class="s1"> *data;</span></p><p class="p1"><span class="s6">    </span><span class="s1">//remove each element</span></p><p class="p5"><span class="s1">    </span><span class="s4">while</span><span class="s1"> (</span><span class="s4">clist_size</span><span class="s1">(clist) != 0) {</span></p><p class="p5"><span class="s1">        </span><span class="s4">if</span><span class="s1">(</span><span class="s5">clist_rem_next</span><span class="s1">(clist, clist-></span><span class="s5">head</span><span class="s1">, (</span><span class="s4">void</span><span class="s1">**) &data) == 0 && clist-></span><span class="s5">destroy</span><span class="s1"> != </span><span class="s4">NULL</span><span class="s1">){</span></p><p class="p5"><span class="s1">            clist-></span><span class="s5">destroy</span><span class="s1">(data);</span></p><p class="p5"><span class="s1">        }</span></p><p class="p5"><span class="s1">    }</span></p><p class="p1"><span class="s6">    </span><span class="s1">//clist</span><span class="s2">清除</span></p><p class="p5"><span class="s1">    </span><span class="s4">memset</span><span class="s1">(clist, 0, </span><span class="s4">sizeof</span><span class="s1">(</span><span class="s5">CList</span><span class="s1">));</span></p><p class="p5"><span class="s1">}</span></p><p class="p1"><span class="s1">/* 1: insert</span><span class="s2">操作</span></p><p class="p1"><span class="s1"> */</span></p><p class="p1"><span class="s1">/* </span><span class="s2">插入成功返回</span><span class="s1">0 </span><span class="s2">,反之返回</span><span class="s1"> -1 */</span></p><p class="p2"><span class="s1"></span>
</p><p class="p6"><span class="s7">/* </span><span class="s1">将元素插入由</span><span class="s7">list</span><span class="s1">指针的循环链表中</span><span class="s7">element</span><span class="s1">之后,</span></p><p class="p7"><span class="s1"> </span></p><p class="p6"><span class="s7"> </span><span class="s1">当插入空链表中时</span><span class="s7">,element</span><span class="s1">可能指向</span></p><p class="p6"><span class="s7"> </span><span class="s1">任何位置,为了避免混淆</span><span class="s7">,element</span><span class="s1">此时应该设置为</span><span class="s7">NULL</span><span class="s1">。</span></p><p class="p7"><span class="s1"> </span></p><p class="p6"><span class="s7"> </span><span class="s1">新的元素包含一个指向</span><span class="s7">data</span><span class="s1">的指针,</span></p><p class="p6"><span class="s7"> </span><span class="s1">因此只要该元素仍在链表中,</span><span class="s7">data</span><span class="s1">所引用的内存空间就应该保持合法</span><span class="s7">.</span><span class="s1">由调用者负责管理</span><span class="s7">data</span></p><p class="p6"><span class="s7"> </span><span class="s1">所引用的存储空间</span><span class="s7">.</span></p><p class="p1"><span class="s1"> */</span></p><p class="p1"><span class="s1">/* O(1)*/</span></p><p class="p3"><span class="s1">int</span></p><p class="p5"><span class="s1">clist_ins_next(</span><span class="s5">CList</span><span class="s1"> *clist, </span><span class="s5">CListElmt</span><span class="s1"> *element, </span><span class="s4">const</span><span class="s1"> </span><span class="s4">void</span><span class="s1"> *data){</span></p><p class="p5"><span class="s1">    </span><span class="s5">CListElmt</span><span class="s1"> *new_element;</span></p><p class="p5"><span class="s1">    </span><span class="s4">if</span><span class="s1">((new_element = (</span><span class="s5">CListElmt</span><span class="s1">*)</span><span class="s5">malloc</span><span class="s1">(</span><span class="s4">sizeof</span><span class="s1">(</span><span class="s5">CListElmt</span><span class="s1">))) == </span><span class="s4">NULL</span><span class="s1">){</span></p><p class="p5"><span class="s1">        </span><span class="s4">return</span><span class="s1"> -1;</span></p><p class="p5"><span class="s1">    }</span></p><p class="p5"><span class="s1">    new_element-></span><span class="s5">data</span><span class="s1"> = (</span><span class="s4">void</span><span class="s1">*)data;</span></p><p class="p6"><span class="s8">    </span><span class="s7">//</span><span class="s1">空表时候插入操作</span></p><p class="p5"><span class="s1">    </span><span class="s4">if</span><span class="s1">(</span><span class="s4">clist_size</span><span class="s1">(clist) == 0){</span></p><p class="p5"><span style="color:#cc0000;"><span class="s1">        new_element-></span><span class="s5">next</span><span class="s1"> = new_element;</span></span></p><p class="p5"><span style="color:#cc0000;"><span class="s1">        clist-></span><span class="s5">head</span><span class="s1"> = new_element;</span></span></p><p class="p1"><span style="color:#cc0000;"><span class="s6">    }</span><span class="s4">else</span><span class="s6">{ </span><span class="s1">//</span><span class="s2">非空表时候的操作操作</span></span></p><p class="p5"><span style="color:#cc0000;"><span class="s1">        new_element-></span><span class="s5">next</span><span class="s1"> = element-></span><span class="s5">next</span><span class="s1">;</span></span></p><p class="p5"><span style="color:#cc0000;"><span class="s1">        element-></span><span class="s5">next</span><span class="s1"> = new_element;</span></span></p><p class="p5"><span class="s1">    }</span></p><p class="p1"><span class="s6">    </span><span class="s1">//size</span><span class="s2">自增</span></p><p class="p5"><span class="s1">    clist-></span><span class="s5">size</span><span class="s1">++;</span></p><p class="p5"><span class="s1">    </span><span class="s4">return</span><span class="s1"> 0;</span></p><p class="p5"><span class="s1">}</span></p><p class="p2"><span class="s1"></span>
</p><p class="p1"><span class="s1">/* 1: remove</span><span class="s2">操作:将移除由参数</span><span class="s1">list</span><span class="s2">指定的</span><span class="s1"> </span><span class="s2">循环表中</span><span class="s1">element</span><span class="s2">后面的元素</span><span class="s1"> </span><span class="s2">。</span></p><p class="p6"><span class="s7"> 2: </span><span class="s1">返回时候</span><span class="s7"> data</span><span class="s1">指向已经</span><span class="s7"> </span><span class="s1">移除元素中存储的数据</span></p><p class="p6"><span class="s7"> 3: </span><span class="s1">由调用者负责管理于</span><span class="s7">data</span><span class="s1">想关联的内存(存储空间)</span></p><p class="p1"><span class="s1"> */</span></p><p class="p1"><span class="s1">/* </span><span class="s2">删除成功返回</span><span class="s1">0 </span><span class="s2">,反之返回</span><span class="s1"> -1 */</span></p><p class="p1"><span class="s1">/* O(1)*/</span></p><p class="p2"><span class="s1"></span>
</p><p class="p3"><span class="s1">int</span></p><p class="p5"><span class="s1">clist_rem_next(</span><span class="s5">CList</span><span class="s1"> *clist, </span><span class="s5">CListElmt</span><span class="s1"> *element, </span><span class="s4">void</span><span class="s1"> **data){</span></p><p class="p5"><span class="s1">    </span><span class="s5">CListElmt</span><span class="s1"> *old_element;</span></p><p class="p6"><span class="s8">    </span><span class="s7">//</span><span class="s1">不允许从一个空链表</span><span class="s7"> </span><span class="s1">移除节点</span></p><p class="p5"><span class="s1">    </span><span class="s4">if</span><span class="s1">(</span><span class="s4">clist_size</span><span class="s1">(clist) == 0){</span></p><p class="p5"><span class="s1">        </span><span class="s4">return</span><span class="s1"> -1;</span></p><p class="p5"><span class="s1">    }</span></p><p class="p5"><span class="s1">    *data = element-></span><span class="s5">next</span><span class="s1">-></span><span class="s5">data</span><span class="s1">;</span></p><p class="p6"><span class="s8">    </span><span class="s7">//</span><span class="s1">自己指向自己</span><span class="s7"> (</span><span class="s1">链表中只有一个元素的情况</span><span class="s7">)</span></p><p class="p5"><span class="s1">    </span><span class="s4">if</span><span class="s1">(element-></span><span class="s5">next</span><span class="s1"> == element){</span></p><p class="p1"><span class="s6">        </span><span class="s1">/* handle  removing the last element*/</span></p><p class="p5"><span class="s1">        old_element = element-></span><span class="s5">next</span><span class="s1">;</span></p><p class="p5"><span class="s1">        clist-></span><span class="s5">head</span><span class="s1"> = </span><span class="s4">NULL</span><span class="s1">;</span></p><p class="p5"><span class="s1">    }</span></p><p class="p5"><span class="s1">    </span><span class="s4">else</span><span class="s1">{</span></p><p class="p1"><span class="s6">        </span><span class="s1">/* handle  removing the last element*/</span></p><p class="p5"><span class="s1">        old_element = element-></span><span class="s5">next</span><span class="s1">;</span></p><p class="p5"><span class="s1">        element-></span><span class="s5">next</span><span class="s1"> = old_element-></span><span class="s5">next</span><span class="s1">;</span></p><p class="p6"><span class="s8">        </span><span class="s7">//</span><span class="s1">如果要删除的</span><span class="s7"> </span><span class="s1">元素</span><span class="s7"> </span><span class="s1">是头元素</span><span class="s7"> </span><span class="s1">则需要</span><span class="s7"> </span><span class="s1">特殊处理</span><span class="s7"> (</span><span class="s1">指向</span><span class="s7"> </span><span class="s1">要删除元素的</span><span class="s7"> </span><span class="s1">下一个位置的元素</span><span class="s7">)</span></p><p class="p5"><span class="s1">        </span><span class="s4">if</span><span class="s1">(old_element == </span><span class="s4">clist_head</span><span class="s1">(clist)){</span></p><p class="p5"><span class="s1">            clist-></span><span class="s5">head</span><span class="s1"> = old_element-></span><span class="s5">next</span><span class="s1">;</span></p><p class="p5"><span class="s1">        }</span></p><p class="p5"><span class="s1">    }</span></p><p class="p5"><span class="s1">    </span><span class="s5">free</span><span class="s1">(old_element);</span></p><p class="p5"><span class="s1">    clist-></span><span class="s5">size</span><span class="s1"> --;</span></p><p class="p5"><span class="s1">    </span><span class="s4">return</span><span class="s1"> 0;</span></p><p class="p5"><span class="s1">}</span></p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p3"><span class="s1">void</span></p><p class="p5"><span class="s1">cprint_list(</span><span class="s4">const</span><span class="s1"> </span><span class="s5">CList</span><span class="s1"> *clist) {</span></p><p class="p5"><span class="s1">    </span><span class="s5">CListElmt</span><span class="s1"> *element = </span><span class="s4">clist_head</span><span class="s1">(clist);</span></p><p class="p5"><span class="s1">    </span><span class="s4">int</span><span class="s1"> *data;</span></p><p class="p5"><span class="s1">    </span><span class="s4">int</span><span class="s1"> i = 0;</span></p><p class="p5"><span class="s1">    </span><span class="s4">if</span><span class="s1">(element != </span><span class="s4">NULL</span><span class="s1">){</span></p><p class="p5"><span class="s1">        </span><span class="s4">do</span><span class="s1">{</span></p><p class="p5"><span class="s1">            data = </span><span class="s4">clist_data</span><span class="s1">(element);</span></p><p class="p4"><span class="s6">            </span><span class="s5">printf</span><span class="s6">(</span><span class="s1">"cprint_list======>list[%d]=%d\n"</span><span class="s6">, i, *data);</span></p><p class="p5"><span class="s1">            element = element-></span><span class="s5">next</span><span class="s1">;</span></p><p class="p5"><span class="s1">            i++;</span></p><p class="p5"><span class="s1">        }</span><span class="s4">while</span><span class="s1"> (element != </span><span class="s4">clist_head</span><span class="s1">(clist));</span></p><p class="p5"><span class="s1">    }</span></p><p class="p2"><span class="s1">    </span></p><p class="p5"><span class="s1">}</span></p><p class="p2"><span class="s1"></span></p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p><p class="p2"><span class="s1"></span>
</p>





你可能感兴趣的:(C 算法精介----链表->循环链表)