java 线性表---------双向链表(源代码)

1.public class DuLinkList<T>   
2.{   
3.    //定义一个内部类Node,Node实例代表链表的节点。   
4.    private class Node   
5.    {   
6.        //保存节点的数据   
7.        private T data;   
8.        //指向上个节点的引用   
9.        private Node prev;   
10.        //指向下个节点的引用   
11.        private Node next;   
12.        //无参数的构造器   
13.        public Node()   
14.        {   
15.        }   
16.        //初始化全部属性的构造器   
17.        public Node(T data , Node prev , Node next)   
18.        {   
19.            this.data = data;   
20.            this.prev = prev;   
21.            this.next = next;   
22.        }   
23.    }   
24.    //保存该链表的头节点   
25.    private Node header;   
26.    //保存该链表的尾节点   
27.    private Node tail;   
28.    //保存该链表中已包含的节点数   
29.    private int size;   
30.    //创建空链表   
31.    public DuLinkList()   
32.    {   
33.        //空链表,header和tail都是null   
34.        header = null;   
35.        tail = null;   
36.    }   
37.    //以指定数据元素来创建链表,该链表只有一个元素   
38.    public DuLinkList(T element)   
39.    {   
40.        header = new Node(element , null , null);   
41.        //只有一个节点,header、tail都指向该节点   
42.        tail = header;   
43.        size++;   
44.    }   
45.    //返回链表的长度      
46.    public int length()   
47.    {   
48.        return size;   
49.    }   
50.  
51.    //获取链式线性表中索引为index处的元素   
52.    public T get(int index)   
53.    {   
54.        return getNodeByIndex(index).data;   
55.    }   
56.    //根据索引index获取指定位置的节点   
57.    private Node getNodeByIndex(int index)   
58.    {   
59.        if (index < 0 || index > size - 1)   
60.        {   
61.            throw new IndexOutOfBoundsException("线性表索引越界");   
62.        }   
63.        if (index <= size / 2)   
64.        {   
65.            //从header节点开始   
66.            Node current = header;   
67.            for (int i = 0 ; i <= size / 2 && current != null  
68.                ; i++ , current = current.next)   
69.            {   
70.                if (i == index)   
71.                {   
72.                    return current;   
73.                }   
74.            }   
75.        }   
76.        else  
77.        {   
78.            //从tail节点开始搜索   
79.            Node current = tail;   
80.            for (int i = size - 1 ; i > size / 2 && current != null  
81.                ; i++ , current = current.prev)   
82.            {   
83.                if (i == index)   
84.                {   
85.                    return current;   
86.                }   
87.            }   
88.        }   
89.        return null;   
90.    }   
91.    //查找链式线性表中指定元素的索引   
92.    public int locate(T element)   
93.    {   
94.        //从头节点开始搜索   
95.        Node current = header;   
96.        for (int i = 0 ; i < size && current != null  
97.            ; i++ , current = current.next)   
98.        {   
99.            if (current.data.equals(element))   
100.            {   
101.                return i;   
102.            }   
103.        }   
104.        return -1;   
105.    }   
106.    //向线性链式表的指定位置插入一个元素。   
107.    public void insert(T element , int index)   
108.    {   
109.        if (index < 0 || index > size)   
110.        {   
111.            throw new IndexOutOfBoundsException("线性表索引越界");   
112.        }   
113.        //如果还是空链表   
114.        if (header == null)   
115.        {   
116.            add(element);   
117.        }   
118.        else  
119.        {   
120.            //当index为0时,也就是在链表头处插入   
121.            if (index == 0)   
122.            {   
123.                addAtHeader(element);   
124.            }   
125.            else  
126.            {   
127.                //获取插入点的前一个节点   
128.                Node prev = getNodeByIndex(index - 1);   
129.                //获取插入点的节点   
130.                Node next = prev.next;   
131.                //让新节点的next引用指向next节点,prev引用指向prev节点   
132.                Node newNode = new Node(element , prev , next);   
133.                //让prev的next指向新节点。   
134.                prev.next = newNode;   
135.                //让prev的下一个节点的prev指向新节点   
136.                next.prev = newNode;   
137.                size++;   
138.            }   
139.        }   
140.    }   
141.    //采用尾插法为链表添加新节点。   
142.    public void add(T element)   
143.    {   
144.        //如果该链表还是空链表   
145.        if (header == null)   
146.        {   
147.            header = new Node(element , null , null);   
148.            //只有一个节点,header、tail都指向该节点   
149.            tail = header;   
150.        }   
151.        else  
152.        {   
153.            //创建新节点,新节点的pre指向原tail节点   
154.            Node newNode = new Node(element , tail , null);   
155.            //让尾节点的next指向新增的节点   
156.            tail.next = newNode;   
157.            //以新节点作为新的尾节点   
158.            tail = newNode;   
159.        }   
160.        size++;   
161.    }   
162.    //采用头插法为链表添加新节点。   
163.    public void addAtHeader(T element)   
164.    {   
165.        //创建新节点,让新节点的next指向原来的header   
166.        //并以新节点作为新的header   
167.        header = new Node(element , null , header);   
168.        //如果插入之前是空链表   
169.        if (tail == null)   
170.        {   
171.            tail = header;   
172.        }   
173.        size++;   
174.    }   
175.    //删除链式线性表中指定索引处的元素   
176.    public T delete(int index)   
177.    {   
178.        if (index < 0 || index > size - 1)   
179.        {   
180.            throw new IndexOutOfBoundsException("线性表索引越界");   
181.        }   
182.        Node del = null;   
183.        //如果被删除的是header节点   
184.        if (index == 0)   
185.        {   
186.            del = header;   
187.            header = header.next;   
188.            //释放新的header节点的prev引用   
189.            header.prev = null;   
190.        }   
191.        else  
192.        {   
193.            //获取删除点的前一个节点   
194.            Node prev = getNodeByIndex(index - 1);   
195.            //获取将要被删除的节点   
196.            del = prev.next;   
197.            //让被删除节点的next指向被删除节点的下一个节点。   
198.            prev.next = del.next;   
199.            //让被删除节点的下一个节点的prev指向prev节点。   
200.            if (del.next != null)   
201.            {   
202.                del.next.prev = prev;   
203.            }          
204.            //将被删除节点的prev、next引用赋为null.   
205.            del.prev = null;   
206.            del.next = null;   
207.        }   
208.        size--;   
209.        return del.data;   
210.    }   
211.    //删除链式线性表中最后一个元素   
212.    public T remove()   
213.    {   
214.        return delete(size - 1);   
215.    }   
216.    //判断链式线性表是否为空链表   
217.    public boolean empty()   
218.    {   
219.        return size == 0;   
220.    }   
221.    //清空线性表   
222.    public void clear()   
223.    {   
224.        //将底层数组所有元素赋为null   
225.        header = null;   
226.        tail = null;   
227.        size = 0;   
228.    }   
229.    public String toString()   
230.    {   
231.        //链表为空链表时   
232.        if (empty())   
233.        {   
234.            return "[]";   
235.        }   
236.        else  
237.        {   
238.            StringBuilder sb = new StringBuilder("[");   
239.            for (Node current = header ; current != null  
240.                ; current = current.next )   
241.            {   
242.                sb.append(current.data.toString() + ", ");   
243.            }   
244.            int len = sb.length();   
245.            return sb.delete(len - 2 , len).append("]").toString();   
246.        }   
247.    }   
248.    public String reverseToString()   
249.    {   
250.        //链表为空链表时   
251.        if (empty())   
252.        {   
253.            return "[]";   
254.        }   
255.        else  
256.        {   
257.            StringBuilder sb = new StringBuilder("[");   
258.            for (Node current = tail ; current != null    
259.                ; current = current.prev )   
260.            {   
261.                sb.append(current.data.toString() + ", ");   
262.            }   
263.            int len = sb.length();   
264.            return sb.delete(len - 2 , len).append("]").toString();   
265.        }   
266.    }   
267.       
268.    public static void main(String[] args)    
269.    {   
270.        DuLinkList<String> list = new DuLinkList<String>();   
271.        list.insert("aaaa" , 0);   
272.        list.add("bbbb");   
273.        list.insert("cccc" , 0);   
274.        //在索引为1处插入一个新元素   
275.        list.insert("dddd" , 1);   
276.        //输出顺序线性表的元素   
277.        System.out.println(list);   
278.        //删除索引为2处的元素   
279.        list.delete(2);   
280.        System.out.println(list);   
281.        System.out.println(list.reverseToString());   
282.        //获取cccc字符串在顺序线性表中的位置   
283.        System.out.println("cccc在顺序线性表中的位置:"    
284.            + list.locate("cccc"));   
285.        System.out.println("链表中索引1处的元素:"    
286.            + list.get(1));   
287.        list.remove();   
288.        System.out.println("调用remove方法后的链表:" + list);   
289.        list.delete(0);   
290.        System.out.println("调用delete(0)后的链表:" + list);   
291.    }   
292.}  

源码,经典。 CARD *myinsert(LCARD *head, LCARD *insert) { LCARD *temp = NULL; if (head==NULL)//链表为空 { head = insert; insert->next = insert; insert->prior = insert; } else//链表非空 { temp = head; if (head->cardnum>insert->cardnum)//插入到头前边,并且把自己当作头 { head->prior->next = insert; insert->prior = head->prior; insert->next = head; head->prior = insert; head = insert; } if (insert->cardnum0<50)//小于50正向插入 { while ((temp->cardnum<insert->cardnum)&&(temp->next!=head))//循环 { temp = temp->next; } if (temp->cardnum>insert->cardnum)//第一个条件终止的 { temp->prior->next = insert; insert->prior = temp->prior; insert->next = temp; temp->prior = insert; } else//第二个条件终止的 { head->prior->next = insert; insert->prior = head->prior; insert->next = head; head->prior = insert; } } else//大于50反向插入 { while ((temp->cardnum>insert->cardnum)&&(temp->prior!=head))//循环,第二个条件禁止跑飞 { temp = temp->prior; } if (temp->cardnum<insert->cardnum)//只有第一个条件可以终止的 { temp->next->prior = insert; insert->next = temp->next; insert->prior = temp; temp->next = insert; } } } //printf("%d\t%d\n", insert->id, insert->cardnum); return head; } void swap_id(SWID *sw) { LCARD *temp = sw->head; if (sw->head->cardnum==sw->swapcardnum) { printf("out person cardnum=%d\n", sw->head->id); sw->head->id = sw->inID; return ; } if ((sw->swapcardnum0)<50) { while ((temp->cardnum!=sw->swapcardnum)&&(temp->next!=sw->head)) { temp = temp->next; } if (temp->cardnum==sw->swapcardnum) { printf("out person cardnum=%d\n", sw->head->id); temp->id = sw->inID; } } else { while ((temp->cardnum!=sw->swapcardnum)&&(temp->prior!=sw->head)) { temp = temp->prior; } if (temp->cardnum==sw->swapcardnum) { printf("out person cardnum=%d\n", sw->head->id); temp->id = sw->inID; } } } LCARD *mydel(LCARD *head, LCARD *del) { LCARD *temp = NULL; if (head==NULL)//没有链表 { printf("there is no card\n"); } else//有链表 { if(head->next==head)//链表里就有一个节点并且为头结点 { if (head->cardnum==del->cardnum) { free(head); head = NULL; } else { printf("in mydel error\n"); } } else//链表里有超过一个的节点 { temp = head; if (del->cardnum0<50)//成立则正向删除 { while ((temp->cardnum!=del->cardnum)&&(temp->next!=head)) { temp = temp->next; } if (temp->cardnum==del->cardnum) { temp->prior->next = temp->next; temp->next->prior = temp->prior; free(temp); } } else//反向删除 { while ((temp->cardnum!=del->cardnum)&&(temp->prior!=head)) { temp = temp->prior; } if (temp->cardnum==del->cardnum) { temp->prior->next = temp->next; temp->next->prior = temp->prior; free(temp); } } } } return head; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值