双向链表排序c语言程序设计

双向链表排序c语言程序设计,第1张

/************************************************************************/

/*

文件名 doublelnk.h

作用 定义必要的结构体,并对双向链表的 *** 作函数做声明

*/

/************************************************************************/

#ifndef DList_H

#define DList_H

typedef  int Item

typedef struct Node * PNode

typedef PNode Position

/*定义节点类型*/

typedef struct Node

{

Item id /*编号*/

Item data /*数据域*/

PNode previous /*指向前驱*/

PNode next /*指向后继*/

}Node

/*定义链表类型*/

typedef struct

{

PNode head /*指向头节点*/

PNode tail /*指向尾节点*/

int size

}DList

enum enumSortType

{

ID,

DATA

}

/*分配值为i的节点,并返回节点地址*/

Position MakeNode(Item id, Item data)

/*释放p所指的节点*/

void FreeNode(PNode p)

/*构造一个空的双向链表*/

DList* InitList()

/*摧毁一个双向链表*/

void DestroyList(DList *plist)

/*将一个链表置为空表,释放原链表节点空间*/

void ClearList(DList *plist)

/*返回头节点地址*/

Position GetHead(DList *plist)

/*返回尾节点地址*/

Position GetTail(DList *plist)

/*返回链表大小*/

int GetSize(DList *plist)

/*返回p的直接后继位置*/

Position GetNext(Position p)

/*返回p的直接前驱位置*/

Position GetPrevious(Position p)

/*将pnode所指节点插入第一个节点之前*/

PNode InsFirst(DList *plist,PNode pnode)

/*将链表第一个节点删除并返回其地址*/

PNode DelFirst(DList *plist)

/*获得节点的数据项*/

Item GetItem(Position p)

/*设置节点的数据项*/

void SetItem(Position p,Item i)

/*删除链表中的尾节点并返回其地址,改变链表的尾指针指向新的尾节点*/

PNode Remove(DList *plist)

/*在链表中p位置之前插入新节点S*/

PNode InsBefore(DList *plist,Position p,PNode s)

/*在链表中p位置之后插入新节点s*/

PNode InsAfter(DList *plist,Position p,PNode s)

/*返回在链表中第i个节点的位置*/

PNode LocatePos(DList *plist,int i)

void ListTraverse(DList *plist,void (*visit)(Node))

/*对双向链表按照执行的排序方式进行排序*/

void SortDLnk(DList * plist, enumSortType sortType)

void SortDLnkbyID(DList * plist)

void SortDLnkbyData(DList * plist)

void swapnode(PNode anode, PNode bnode)

#endif

/************************************************************************/

/*

文件名 doublelnk.cpp

作用 对双向链表的 *** 作函数进行具体实现

*/

/************************************************************************/

#include"doublelnk.h"

#include<malloc.h>

#include<stdlib.h>

/*分配值为i的节点,并返回节点地址*/

Position MakeNode(Item id, Item data)

{

PNode p = NULL 

p = (PNode)malloc(sizeof(Node))

if(p!=NULL)

{

p->id =id

p->data = data

p->previous = NULL

p->next = NULL

}

return p

}

/*释放p所指的节点*/

void FreeNode(PNode p)

{

free(p)

}

/*构造一个空的双向链表*/

DList * InitList()

{

DList *plist = (DList *)malloc(sizeof(DList))

PNode head = MakeNode(0, 0) 

if(plist!=NULL)

{

if(head!=NULL)

{

plist->head = head

plist->tail = head

plist->size = 0

}

else

return NULL

}

return plist

}

/*摧毁一个双向链表*/

void DestroyList(DList *plist)

{

ClearList(plist)

free(GetHead(plist))

free(plist)

}

/*判断链表是否为空表*/

int IsEmpty(DList *plist)

{

if(GetSize(plist)==0&&GetTail(plist)==GetHead(plist))

return 1

else

return 0

}

/*将一个链表置为空表,释放原链表节点空间*/

void ClearList(DList *plist)

{

PNode temp,p

p = GetTail(plist)

while(!IsEmpty(plist))

{

temp = GetPrevious(p)

FreeNode(p)

p = temp

plist->tail = temp

plist->size--

}

}

/*返回头节点地址*/

Position GetHead(DList *plist)

{

return plist->head

}

/*返回尾节点地址*/

Position GetTail(DList *plist)

{

return plist->tail

}

/*返回链表大小*/

int GetSize(DList *plist)

{

return plist->size

}

/*返回p的直接后继位置*/

Position GetNext(Position p)

{

return p->next

}

/*返回p的直接前驱位置*/

Position GetPrevious(Position p)

{

return p->previous

}

/*将pnode所指节点插入第一个节点之前*/

PNode InsFirst(DList *plist,PNode pnode)

{

Position head = GetHead(plist)

if(IsEmpty(plist))

plist->tail = pnode

plist->size++

pnode->next = head->next

pnode->previous = head

if(head->next!=NULL)

head->next->previous = pnode

head->next = pnode

return pnode 

}

/*将链表第一个节点删除,返回该节点的地址*/

PNode DelFirst(DList *plist)

{

Position head = GetHead(plist)

Position p=head->next

if(p!=NULL)

{

if(p==GetTail(plist))

plist->tail = p->previous

head->next = p->next

head->next->previous = head

plist->size--

}

return p

}

/*获得节点的数据项*/

Item GetItem(Position p)

{

return p->data

}

/*设置节点的数据项*/

void SetItem(Position p,Item i)

{

p->data = i

}

/*删除链表中的尾节点并返回地址,改变链表的尾指针指向新的尾节点*/

PNode Remove(DList *plist)

{

Position p=NULL

if(IsEmpty(plist))

return NULL

else

{

p = GetTail(plist)

p->previous->next = p->next

plist->tail = p->previous

plist->size--

return p

}

}

/*在链表中p位置之前插入新节点s*/

PNode InsBefore(DList *plist,Position p,PNode s)

{

s->previous = p->previous

s->next = p

p->previous->next = s

p->previous = s

plist->size++

return s

}

/*在链表中p位置之后插入新节点s*/

PNode InsAfter(DList *plist,Position p,PNode s)

{

s->next = p->next

s->previous = p

if(p->next != NULL)

p->next->previous = s

p->next = s

if(p = GetTail(plist))

plist->tail = s

plist->size++

return s

}

/*返回在链表中第i个节点的位置*/

PNode LocatePos(DList *plist,int i)

{

int cnt = 0

Position p = GetHead(plist)

if(i>GetSize(plist)||i<1)

return NULL

while(++cnt<=i)

{

p=p->next

}

return p

}

/*依次对链表中每个元素调用函数visit()*/  

void ListTraverse(DList *plist,void (*visit)(Node))  

{  

Position p = GetHead(plist)  

if(IsEmpty(plist))  

exit(0)  

else  

{  

while(p->next!=NULL)  

{  

p = p->next  

visit(*p)            

}         

}  

}  

void SortDLnk(DList * plist, enumSortType sortType)

{

switch(sortType)

{

case ID:

SortDLnkbyID(plist)

break

case DATA:

SortDLnkbyData(plist)

break

}

}

void SortDLnkbyID(DList * plist)

{

PNode head = plist->head

Node tmpnode

Position currnode = head

Position bianlinode

while ((currnode=currnode->next) != NULL)

{

bianlinode =currnode

while((bianlinode=bianlinode->next) != NULL)

{

if (currnode->id > bianlinode->id)

{

swapnode(currnode, bianlinode)

}

}

}

}

void SortDLnkbyData(DList * plist)

{

PNode head = plist->head

Node tmpnode

Position currnode = head

Position bianlinode

while ((currnode=currnode->next) != NULL)

{

bianlinode =currnode

while((bianlinode=bianlinode->next) != NULL)

{

if (currnode->data > bianlinode->data)

{

swapnode(currnode, bianlinode)

}

}

}

}

void swapnode(PNode anode, PNode bnode)

{// 这里面要特别注意防止前驱节点是头结点和后驱节点是Null的情况

Node tmpnode

tmpnode.id = anode->id

tmpnode.data = anode->data

anode->id = bnode->id

anode->data = bnode->data

bnode->id = tmpnode.id

bnode->data = tmpnode.data

}

/************************************************************************/

/*

文件名 program.cpp

作用 对双向链表的 *** 作函数进行测试

*/

/************************************************************************/

#include"doublelnk.h"

#include<stdio.h>

void print(Node node)

{

printf("数据项: id=%d, data=%d \n",node.id, node.data)

}

int main()

{

DList *plist = NULL

PNode p = NULL

plist = InitList()

p = InsFirst(plist,MakeNode(12, 23))

InsBefore(plist,p,MakeNode(2, 54))

InsAfter(plist,p,MakeNode(3, 34))

printf("p前驱位置的值为%d\n",GetItem(GetPrevious(p)))

printf("p位置的值为%d\n",GetItem(p))

printf("p后继位置的值为%d\n",GetItem(GetNext(p)))

printf("遍历输出各节点数据项:\n")

ListTraverse(plist,print)

printf("按照ID排序后遍历输出:\n")

SortDLnk(plist, ID)

ListTraverse(plist,print)

printf("按照Data排序后遍历输出:\n")

SortDLnk(plist, DATA)

ListTraverse(plist,print)

printf("除了头节点该链表共有%d个节点\n",GetSize(plist))

FreeNode(DelFirst(plist))

printf("删除第一个节点后重新遍历输出为:\n")

ListTraverse(plist,print)

printf("除了头节点该链表共有%d个节点\n",GetSize(plist))

DestroyList(plist)

printf("链表已被销毁\n")

return 0

}

程序总共分三部分, 分别是双向链表的头文件、源文件和测试程序

建立工程后,分别建立相应的文件并添加相应代码应该就可以

下面的图片是我的运行效果(声明:程序中很多代码参考了以为前辈的代码http://blog.csdn.net/hopeyouknow/article/details/6716177)

#include <iostream>

using namespace std

class Node {

public:

int element

Node *next

Node *previous

Node(int element, Node *next, Node *previous) {

this->element = element

this->next = next

this->previous = previous

}

}

class LinkedList {

LinkedList()

void addFirst(int)

void addLast(int)

void add(int index, int element)

int getFirst()

int getLast()

int get(int)

int removeFirst()

int removeLast()

int remove(int)

void iterate()

private:

Node *header

int size

}

/*

* 构造方法。

* 生成一个空的节点介于表头和表尾之间,初始前后指针都指向自己。

*/

LinkedList::LinkedList() {

header = new Node(NULL, NULL, NULL)

header->next = header

header->previous = header

size = 0

}

/*

* 在链表头部添加一个元素。

* 生成一个新的节点,向前指向空节点,向后指向原来空节点的下一个节点,即原来的第一个节点。

* 空节点向后指向此节点,原来的第一个节点向前指向此节点。

*/

void LinkedList::addFirst(int i) {

header->next = new Node(i, header->next, header)

header->next->next->previous = header->next

++size

}

/*

* 在链表最后添加一个元素。

* 生成一个新的节点,向前指向原来空节点的前一个节点,即原来的最后一个节点,向后指向空节点。

* 原来的最后一个节点向后指向此节点,空节点向前指向此节点。

*/

void LinkedList::addLast(int i) {

header->previous = new Node(i, header, header->previous)

header->previous->previous->next = header->previous

++size

}

/*

* 在指定的索引前插入一个元素。0 <= 索引 <= 链表长度。

* 如果索引值小于链表长度的一半,向后(正向)迭代获取索引值位置的节点,反之则向前(反向)。

* 生成一个新的节点,向前指向原来这个位置的节点的前一个节点,向后指向原来这个位置的节点。

* 原来这个位置的节点的前一个节点向后指向此节点,原来这个位置的节点向前指向此节点。

* (在指定的索引删除一个元素实现方法类似)

*/

void LinkedList::add(int index, int i) {

if(index >size || index <0) {

cout <<"Exception in add(): Index out of bound." <<'\n'

return

}

Node *entry

if(index <size / 2) {

entry = header->next

for(int i = 0i <index++i)

entry = entry->next

}

else {

entry = header

for(int i = sizei >index--i)

entry = entry->previous

}

entry->previous->next = new Node(i, entry, entry->previous)

entry->previous = entry->previous->next

++size

}

/*

* 获取链表第一个元素。

* 空节点向后指向的节点即是第一个元素。

*/

int LinkedList::getFirst() {

if(!size)

cout <<"Exception in getFirst(): List is empty." <<'\n'

return header->next->element

}

/*

* 获取链表最后一个元素。

* 空节点向前指向的节点即是最后一个元素。

*/

int LinkedList::getLast() {

if(!size)

cout <<"Exception in getLast(): List is empty." <<'\n'

return header->previous->element

}

/*

* 删除并返回链表第一个元素。

* 链表第二个节点向前指向空节点,空节点向后指向第二个节点。

*/

int LinkedList::removeFirst() {

int remove = header->next->element

header->next->next->previous = header

header->next = header->next->next

--size

return remove

}

/*

* 删除并返回链表最后一个元素。

* 链表倒数第二个节点向后指向空节点,空节点向前指向倒数第二个节点。

*/

int LinkedList::removeLast() {

int remove = header->previous->element

header->previous->previous->next = header

header->previous = header->previous->previous

--size

return remove

}

/*

* 用来输出所有元素的迭代方法。

*/

void LinkedList::iterate() {

if(!size) {

cout <<"Exception in iterate(): List is empty." <<'\n'

return

}

for(Node *entry = header->nextentry != headerentry = entry->next)

cout <<entry->element <<" "

cout <<'\n'

}

int main()

{

cout <<"Hello World!" <<endl

return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11685771.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存