栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构 C 代码 2.3: 双向链表

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构 C 代码 2.3: 双向链表

摘要: 双向链表比单链表稍复杂, 也更不常用. 主要是为了练习链表的变种, 寻找更多设计的感觉. 这样在面对实际问题的时候, 就具有一定的建模能力.

1. 代码
#include 
#include 


typedef struct DoubleLinkedNode{
	char data;
	struct DoubleLinkedNode *previous;
	struct DoubleLinkedNode *next;
} DLNode, *DLNodePtr;


DLNodePtr initLinkList(){
	DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
	tempHeader->data = '';
	tempHeader->previous = NULL;
	tempHeader->next = NULL;
	return tempHeader;
}// Of initLinkList


void printList(DLNodePtr paraHeader){
	DLNodePtr p = paraHeader->next;
	while (p != NULL) {
		printf("%c", p->data);
		p = p->next;
	}// Of while
	printf("rn");
}// Of printList


void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
	DLNodePtr p, q, r;

	// Step 1. Search to the position.
	p = paraHeader;
	for (int i = 0; i < paraPosition; i ++) {
		p = p->next;
		if (p == NULL) {
			printf("The position %d is beyond the scope of the list.", paraPosition);
			return;
		}// Of if
	} // Of for i

	// Step 2. Construct a new node.
	q = (DLNodePtr)malloc(sizeof(struct DoubleLinkedNode));
	q->data = paraChar;

	// Step 3. Now link.
	r = p->next;
	q->next = p->next;
	q->previous = p;
	p->next = q;
	if (r != NULL) {
		r->previous = q;
	}// Of if
}// Of insertElement


void deleteElement(DLNodePtr paraHeader, char paraChar){
	DLNodePtr p, q, r;
	p = paraHeader;

	// Step 1. Locate.
	while ((p->next != NULL) && (p->next->data != paraChar)){
		p = p->next;
	}// Of while

	// Step 2. Error check.
	if (p->next == NULL) {
		printf("The char '%c' does not exist.rn", paraChar);
		return;
	}// Of if

	// Step 3. Change links.
	q = p->next;
	r = q->next;
	p->next = r;
	if (r != NULL) {
		r->previous = p;
	}// Of if

	// Step 4. Free the space.
	free(q);
}// Of deleteElement


void insertDeleteTest(){
	// Step 1. Initialize an empty list.
	DLNodePtr tempList = initLinkList();
	printList(tempList);

	// Step 2. Add some characters.
	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);

	// Step 3. Delete some characters (the first occurrence).
	deleteElement(tempList, 'e');
	deleteElement(tempList, 'a');
	deleteElement(tempList, 'o');
	printList(tempList);

	// Step 4. Insert to a given position.
	insertElement(tempList, 'o', 1);
	printList(tempList);
}// Of appendInsertDeleteTest


void basicAddressTest(){
	DLNode tempNode1, tempNode2;

	tempNode1.data = 4;
	tempNode1.next = NULL;

	tempNode2.data = 6;
	tempNode2.next = NULL;

	printf("The first node: %d, %d, %drn",
		&tempNode1, &tempNode1.data, &tempNode1.next);
	printf("The second node: %d, %d, %drn",
		&tempNode2, &tempNode2.data, &tempNode2.next);

	tempNode1.next = &tempNode2;
}// Of basicAddressTest


void main(){
	insertDeleteTest();
	basicAddressTest();
}// Of main
2. 运行结果
Hello!
The char 'a' does not exist.
Hll!
Holl!
The first node: 1703632, 1703632, 1703640
The second node: 1703620, 1703620, 1703628
Press any key to continue
3. 代码说明
  1. 仅实现了打印、插入、删除.
  2. 每个相关指针都要改, 必须画个图来辅助写程序.
  3. 尾结点删除时需要注意. 需要进行边界测试.
4. 作业
  1. 抄代码.
  2. 进行 insertElement 等函数进一步的测试.
  3. 自己实现 locateElement 函数.
  4. 挑本贴 bug 并留言.
  5. 写 CSDN 博客. 必须有图示, 可以用工具画, 或者手绘拍照.

附一. 2021 级代码

麦尔哈巴·阿卜杜拉同学的代码, 注释写得详细.

#include
using namespace std;
typedef int Status;
typedef int ElemType;
#define OVERFLOW -1
#define ERROR 0
#define OK 1

//-----双向链表的储存结构-----
typedef struct DuLNode
{
    ElemType data;
    struct DuLNode *prior;
    struct DuLNode *next;
} DuLNode, *DuLinkList;

DuLinkList L;

//1、双向链表初始化
Status InitList_DuL(DuLinkList &L)
{
    //构造一个空的双向链表L
    L = new DuLNode;
    L->prior = NULL;
    L->next = NULL;
    return OK;
}

//2、双向链表按位查找
DuLNode *GetElem_DuL(DuLinkList L, int i)
{
    DuLNode *p = L->next;
    int j = 1;
    while(p && j < i)
    {
        p = p->next;
        j++;
    }
    if(!p || j > i)
        return NULL;
    else
        return p;
}

//3、双向链表前驱
Status PriorElem_DuL(DuLinkList L, ElemType cur_e, ElemType &pre_e)
{
    DuLNode *p;
    if(!(p = LocateElem_DuL(L, cur_e)))                //在L中确定第i个元素的位置指针p
        return ERROR;
    pre_e = p->prior->data;
    return OK;
}

//4、双向链表后继
Status NextElem_DuL(DuLinkList L, ElemType cur_e, ElemType &next_e)
{
    DuLNode *p;
    if(!(p = LocateElem_DuL(L, cur_e)))                //在L中确定第i个元素的位置指针p
        return ERROR;
    next_e = p->next->data;
    return OK;
}

//5、双向链表插入
Status ListInsert_DuL(DuLinkList &L, int i, ElemType e)
{
    //在带头结点的双向链表L中第i个位置之前插入元素e
    DuLNode *p;
    if(!(p = GetElem_DuL(L, i)))
        return ERROR;
    DuLNode *s = new DuLNode;
    s->data = e;
    s->prior = p->prior;
    p->prior->next = s;
    s->next = p;
    p->prior = s;
    return OK;
}

//11、双向链表删除
Status ListDelete_DuL(DuLinkList &L, int i)
{
    //删除带头结点的双向链表L中的第i个元素
    DuLNode *p;
    if(!(p = GetElem_DuL(L, i)))
        return ERROR;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    delete p;
    return OK;
}

int main()
{
    cout<<"------------------------双向链表菜单----------------------"<<'n';
    cout<<"操作0:退出程序"<<'n';
    cout<<"操作1:创建一个带头结点的双向链表,且遍历此链表"<<'n';
    cout<<"操作2:在双向链表中的第i个结点前插入一个结点值为e的正整数"<<'n';
    cout<<"操作3:删除双向链表链表中的第j个结点"<<'n';
    int a, n, flag = 1;
    while(flag)
    {
        cout<<'n'<<"请选择要执行的操作:";
        while(cin>>a)
        {
            if(a < 0 || a > 5)
                cout<<"请选择正确操作编号:";
            else
                break;
        }
        switch(a)
        {
        case 0:
        {
            cout<<"感谢使用本程序,祝您生活愉快!"<<'n';
            flag = 0;
            break;
        }
        case 1:
        {
            cout<<"----菜单-----"<<'n';
            cout<<"操作1:前插法"<<'n';
            cout<<"操作2:后插法"<<'n';
            cout<<"-------------"<<'n';
            cout<<"请选择单链表的创建方式:";
            int b;
            while(cin>>b)
            {
                if(b != 1 && b != 2)
                    cout<<"请选择正确操作编号:";
                else
                    break;
            }
            cout<<"请输入要建立的单链表的元素个数:";
            cin>>n;
            if(b == 1)
            {
                cout<<"请按逆位序依次输入这"<>i>>e;
            if(ListInsert_DuL(L, i, e))
            {
                cout<<"单链表插入完毕:";
                TraverseList_DuL(L);
            }
            else
                cout<<"i值不合法!"<<'n';
            break;
        }
        case 3:
        {
            int j;
            cout<<"删除单链表中的第j个结点,请输入j的值:";
            cin>>j;
            if(ListDelete_DuL(L, j))
            {
                cout<<"单链表删除完毕:";
                TraverseList_DuL(L);
            }
            else
                cout<<"j值不合法!"<<'n';
            break;
        }
        }
    }
    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/850846.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号