数据结构课程设计-- 循环单链表

合集下载

单链表课程设计

单链表课程设计

单链表课程设计一、课程目标知识目标:1. 学生能理解单链表的基本概念,掌握其结构特点及在数据结构中的重要性。

2. 学生能够运用所学知识,实现单链表的创建、插入、删除和查找等基本操作。

3. 学生能够掌握单链表与数组、栈、队列等其他数据结构的关系与区别。

技能目标:1. 学生能够运用编程语言(如C、C++等)实现单链表的相关操作,提高编程能力。

2. 学生能够通过实际操作,培养解决实际问题的能力,提高逻辑思维能力。

情感态度价值观目标:1. 学生通过学习单链表,培养对数据结构的兴趣,提高学习积极性。

2. 学生在学习过程中,学会与他人合作,培养团队精神和沟通能力。

3. 学生能够认识到数据结构在计算机科学中的重要性,增强对专业知识的认同感。

课程性质分析:本课程为计算机科学与技术专业的基础课程,旨在让学生掌握单链表这一基础数据结构,为后续学习更复杂的数据结构打下基础。

学生特点分析:学生已具备基本的编程能力,具有一定的逻辑思维能力,但可能对数据结构的应用场景认识不足,需要通过实际案例激发兴趣。

教学要求:1. 结合实际案例,讲解单链表的理论知识,让学生了解其在实际问题中的应用。

2. 通过课堂讲解、上机实践等教学手段,让学生掌握单链表的相关操作。

3. 注重培养学生的编程能力和逻辑思维能力,提高解决实际问题的能力。

二、教学内容1. 单链表基本概念:介绍单链表的定义、结构特点及其在数据结构中的应用场景。

- 教材章节:第二章第二节- 内容安排:讲解单链表的组成元素(节点、指针)、分类(单向、双向)及优缺点。

2. 单链表基本操作:- 教材章节:第二章第三节- 内容安排:讲解单链表的创建、插入、删除、查找等基本操作,并通过实例演示。

3. 单链表与其它数据结构的对比:- 教材章节:第二章第四节- 内容安排:分析单链表与数组、栈、队列等其他数据结构的区别和联系,突出单链表的特点。

4. 单链表编程实践:- 教材章节:第二章第五节- 内容安排:结合上机实践,让学生动手实现单链表的基本操作,培养编程能力和解决实际问题的能力。

数据结构实验报告--单链表

数据结构实验报告--单链表

数据结构实验报告--单链表数据结构实验报告--单链表1.引言1.1 研究目的本实验旨在通过实践的方式,深入了解单链表的数据结构以及相关操作,提升对数据结构的理解和应用能力。

1.2 实验内容本实验主要包括以下几个方面的内容:●单链表的基本定义和实现●单链表的插入、删除、遍历操作●单链表的逆置操作●单链表的查找和修改操作2.理论基础2.1 单链表的定义单链表是一种常见的线性数据结构,它由一系列的节点组成,每个节点包含数据和指向下一个节点的指针。

2.2 单链表的基本操作①单链表的插入操作在单链表中,可以通过插入操作在指定位置插入一个新节点,该操作主要包括以下步骤:●创建一个新的节点,并为其赋值●将新节点的next指针指向插入位置的后一个节点●将插入位置的前一个节点的next指针指向新节点②单链表的删除操作在单链表中,可以通过删除操作删除指定位置的节点,该操作主要包括以下步骤:●将删除位置的前一个节点的next指针指向删除位置的后一个节点●释放删除节点的内存③单链表的遍历操作单链表的遍历操作主要是依次访问链表中的每一个节点,并执行相应的操作。

④单链表的逆置操作单链表的逆置操作可以将一个单链表中的节点顺序进行颠倒。

⑤单链表的查找操作在单链表中,可以通过查找操作找到指定值的节点。

⑥单链表的修改操作在单链表中,可以通过修改操作修改指定位置的节点的值。

3.实验过程3.1 实验环境本次实验使用C语言进行编程,需要先安装相应的编程环境,如gcc编译器。

3.2 实验步骤①单链表的创建和初始化首先创建一个空链表,并初始化链表的头指针。

②单链表的插入操作按照需求,在链表的指定位置插入一个新节点。

③单链表的删除操作按照需求,删除链表中的指定位置的节点。

④单链表的遍历操作依次访问链表中的每一个节点,并输出其值。

⑤单链表的逆置操作将单链表中的节点顺序进行逆置。

⑥单链表的查找操作按照需求,在链表中查找指定值的节点。

3.2.7 单链表的修改操作按照需求,修改链表中指定位置的节点的值。

数据结构课程设计——约瑟夫环报告(含代码)

数据结构课程设计——约瑟夫环报告(含代码)

#include<stdio.h>#include<stdlib.h>typedef struct LNode{//数据域int cipher; //密码int number; //编号struct LNode *next; //指针域}LNode,*LinkList;void InitList(LinkList &L) //创建一个只有头结点链表{L = (LinkList)malloc(sizeof(LNode));if(!L){exit(1);printf("/n/nError!/n/n");}L->next = L;}void CreateList(int n,LinkList &L) //初始化循环单链表{LinkList p,q;q = L;printf("分别输入每个人的密码:");for(int i = 1;i <= n;i++){int k;scanf("%d",&k);if(k <= 0){printf("\n\n密码有误!\n\n");exit(1);}p = (LinkList)malloc(sizeof(LNode));if(!p){exit(1);printf("/n/nError!/n/n");}p->cipher = k;p->number = i;L->next = p;L = p;}L->next = q->next;free(q);}void PrintList(int x,int n,LinkList L) //输出出列顺序{LinkList p,q;p = L;for(int i = 1;i <= n;i++){for(int j = 1;j < x;j++)p = p->next;q = p->next;x = q->cipher;printf("%d ",q->number);p->next = q->next;free(q);}}int main(){printf("=============约瑟夫环==============\n\n\n");int n,x;LinkList L;L = NULL;InitList(L); //构造空链表printf("输入初始密码:");scanf("%d",&x); //初始密码为xprintf("\n");printf("输入参与总人数:");scanf("%d",&n); //总共的人数nprintf("\n");CreateList(n,L); //建立好一个约瑟夫环printf("\n\n\n===================================\n\n");printf("出列编号为:");PrintList(x,n,L); //输出出列顺序printf("\n\n");return 0;}。

10年《数据结构》课程设计参考题

10年《数据结构》课程设计参考题

10年《数据结构》课程设计参考题数据结构课程设计要求2.学生要发挥自主学习的能力,充分利用时间,安排好课设的时间计划,并在课设过程中不断检测自己的计划完成情况。

3.课程设计完成要求运行界面友好(有菜单)、操作方便、输出结果正确、可读性强,每种操作有验证性输出。

4.按规定时间提交课程设计报告,过期计为0分。

课程设计实习报告封面的书写格式课程设计课程:数据结构题目:专业班级:姓名:学号:设计时间:指导教师:课程设计报告的内容一、设计题目二、运行环境(软、硬件环境)三、算法设计的思想四、算法的流程图五、算法设计分析六、源代码七、运行结果分析八、收获及体会课程设计题一:排序算法比较一、设计目的1.掌握各种排序的基本思想。

2.掌握各种排序方法的算法实现。

3.掌握各种排序方法的优劣分析及花费的时间的计算。

4.掌握各种排序方法所适应的不同场合。

二、设计内容和要求利用随机函数产生3000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并统计每一种排序上机所花费的时间。

--------------------------------------课程设计题二:图的深度周游一、设计目的1.掌握图的邻接表存贮结构。

2.掌握堆栈的基本运算实现。

3.掌握图的邻接表的算法实现。

4.掌握图的深度优先搜索周游算法实现。

二、设计内容和要求对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用堆栈的五种基本运算(清空堆栈、压栈、弹出、取栈顶元素、判栈空)实现图的深度优先搜索周游。

--------------------------------------课程设计题三:图的广度周游一、设计目的1.掌握图的邻接表存贮结构。

2.掌握队列的基本运算实现。

3.掌握图的邻接表的算法实现。

4.掌握图的广度优先搜索周游算法实现。

二、设计内容和要求对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)实现图的广度优先搜索周游。

数据结构-单链表实验报告

数据结构-单链表实验报告

单链表实验报告一、实验目的1、帮助读者复习C++语言程序设计中的知识。

2、熟悉线性表的逻辑结构。

3、熟悉线性表的基本运算在两种存储结构上的实现,其中以熟悉链表的操作为侧重点。

二、实验内容[问题描述]实现带头结点的单链表的建立、求长度,取元素、修改元素、插入、删除等单链表的基本操作。

[基本要求](1)依次从键盘读入数据,建立带头结点的单链表;(2)输出单链表中的数据元素(3)求单链表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。

三、算法设计(1)建立带表头结点的单链表;首先输入结束标志,然后建立循环逐个输入数据,直到输入结束标志。

(2)输出单链表中所有结点的数据域值;首先获得表头结点地址,然后建立循环逐个输出数据,直到地址为空。

(3)输入x,y在第一个数据域值为x的结点之后插入结点y,若无结点x,则在表尾插入结点y;建立两个结构体指针,一个指向当前结点,另一个指向当前结点的上一结点,建立循环扫描链表。

当当前结点指针域不为空且数据域等于x的时候,申请结点并给此结点数据域赋值为y,然后插入当前结点后面,退出函数;当当前结点指针域为空的时候,申请结点并给此结点数据域赋值为y,插入当前结点后面,退出函数。

(4)输入k,删除单链表中所有的结点k,并输出被删除结点的个数。

建立三个结构体指针,一个指向当前结点,另一个指向当前结点的上一结点,最后一个备用;建立整形变量l=0;建立循环扫描链表。

当当前结点指针域为空的时候,如果当前结点数据域等于k,删除此结点,l++,跳出循环,结束操作;如果当前结点数据域不等于k,跳出循环,结束操作。

当当前结点指针域不为空的时候,如果当前结点数据域等于k,删除此结点,l++,继续循环操作;如果当前结点数据域不等于k,指针向后继续扫描。

循环结束后函数返回变量l的值,l便是删除的结点的个数。

四、实验结果1、新建一个链表:2、输出链表的数据:(4)插入数据:在数据为3后面插入一个数据100:(5)删除数据:删除刚刚插入的数据100:五、总结实验之前由于准备不够充分,所以堂上实验时只完成了建立单链表和数据的输出,而后面两个实验要求也是用来很多时间长完成的。

数据结构课件单链表

数据结构课件单链表
删除节点
删除链表中的节点需要遍历至指定位置,时间复杂度为 O(n)。
查找节点
在链表中查找一个节点需要遍历整个链表,时间复杂度为 O(n)。
空间复杂度
空间占用
单链表的空间占用主要取决于链表中的 节点数,因此空间复杂度为O(n)。
VS
内存分配
每个节点需要分配内存空间存储数据和指 针,因此内存分配的空间复杂度也为O(n) 。
需要根据数据元素顺 序进行遍历的场景, 如排序算法等。
需要频繁插入、删除 操作的场景,如动态 规划、图算法等。
02
单链表的实现
创建单链表
定义节点结构体
首先需要定义一个节点结构体,包含 数据域和指针域两个部分,数据域用 于存储数据,指针域用于指向下一个 节点。
初始化头节点
创建一个头节点,并将其指针域指向 NULL,表示单链表的起始位置。
05
单链表常见问题与解决方 案
循环链表
总结词
循环链表是一种特殊类型的单链表,其中尾节点的指针指向头节点,形成一个闭环。
详细描述
在循环链表中,由于尾节点的指针指向头节点,因此遍历链表时需要特别注意,以避免无限循环。常见的解决方 法是在遍历时记录已经访问过的节点,避免重复访问。
链表中的重复元素
总结词
链表中可能存在重复元素的问题,这会影响数据处理的正确性。
详细描述
为了解决这个问题,可以在插入节点时检查新元素是否已存在于链表中。如果存在,则不进行插入操 作。另外,也可以使用哈希表等数据结构来快速查找重复元素。
链表的排序
总结词
对链表进行排序是常见的需求,但链表的排 序算法通常比数组的排序算法复杂。
合并单链表
总结词
将两个已排序的单链表合并为一个新的已排序的单链表。

第3周线性表(下)第2讲-循环链表

第3周线性表(下)第2讲-循环链表

循环链表是另一种形式的链式存储结构形式。

循环单链表:将表中尾节点的指针域改为指向表头节点,整个链表形成一个环。

由此从表中任一节点出发均可找到链表中其他节点。

循环双链表:形成两个环。

节点类型与非循环单链表的相同节点类型与非循环双链表的相同线性表(a 1, a 2, …, a i , … a n )映射逻辑结构存储结构a 1a 2a n…L带头节点循环单链表示意图1、循环单链表与非循环单链表相比,循环单链表:链表中没有空指针域p所指节点为尾节点的条件:p->next==LL pa1a2a n…【例2-8】某线性表最常用的操作是在尾元素之后插入一个元素和删除第一个元素,故采用存储方式最节省运算时间。

A.单链表B.仅有头结点指针的循环单链表C.双链表D.仅有尾结点指针的循环单链表D.仅有尾结点指针的循环单链表a 1a2a n…L在尾元素之后插入一个元素删除第一个元素时间复杂度均为O(1)选择D线性表(a 1, a 2, … , a i , … a n )映射逻辑结构存储结构a 1a 2a n…L带头节点循环双链表示意图2、循环双链表与非循环双链表相比,循环双链表:链表中没有空指针域p所指节点为尾节点的条件:p->next==L一步操作即L->prior可以找到尾节点p La1a2a n…【例2-9】如果对含有n(n>1)个元素的线性表的运算只有4种,即删除第一个元素、删除尾元素、在第一个元素前面插入新元素、在尾元素的后面插入新元素,则最好使用。

A.只有尾结点指针没有头结点的循环单链表B.只有尾结点指针没有头结点的非循环双链表C.只有首结点指针没有尾结点指针的循环双链表D.既有头指针也有尾指针的循环单链表a 1a 2a n…LC.只有首结点指针没有尾结点指针的循环双链表删除第一个元素删除尾元素在第一个元素前面插入新元素在尾元素的后面插入新元素时间复杂度均为O(1)选择C【例2-10】设计判断带头节点的循环双链表L(含两个以上的节点)是否对称相等的算法。

数据结构课程设计约瑟夫环

数据结构课程设计约瑟夫环

《数据结构》课程设计报告书题目:约瑟夫环系别:计算机科学与应用学号:学生姓名:指导教师:完成日期:2012年6月7日目录1.需求分析 (3)1.1 功能分析 (3)1.2开发平台 (3)2.概要设计 (3)3. 程序设计主要流程 (5)4.调试与操作说明 (5)4.1调试情况 (5)4.2操作说明 (6)总结 (8)致谢 (9)附录 (9)参考文献 (13)指导教师评语: (14)1.需求分析1.1 功能分析本次选做的课程设计是改进约瑟夫(Joseph)环问题。

约瑟夫环问题是一个古老的数学问题,本次课题要求用程序语言的方式解决数学问题。

此问题仅使用单循环链表就可以解决此问题。

在建立单向循环链表时,因为约瑟夫环的大小由输入决定。

为方便操作,我们将每个结点的数据域的值定为生成结点时的顺序号和每个人持有的密码。

进行操作时,用一个指针r指向当前的结点,指针H指向头结点。

然后建立单向循环链表,因为每个人的密码是通过scanf()函数输入随机生成的,所以指定第一个人的顺序号,找到结点,不断地从链表中删除链结点,直到链表剩下最后一个结点,通过一系列的循环就可以解决改进约瑟夫环问题。

1.2开发平台WindowsXP操作系统;Microsoft Visual C++ 6.0;2.概要设计编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。

一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。

这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。

r->next=H。

解决问题的核心步骤:首先建立一个具有n个链结点,无头结点的循环链表。

然后确定第1个报数人的位置。

最后不断地从链表中删除链结点,直到链表为空。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程设计-- 循环单链表信息科学与技术学院《数据结构》课程设计报告题目名称:循环单链表(附加头结点,引用)专业班级:计算机科学与技术2011级1班学生姓名:**学生学号:**********指导教师:**目录1 课程设计的目的 (1)1.1 课程设计的目的 (1)1.2 课程设计的题目 (1)1.3 题目要求 (1)2 概要设计 (1)2.1 存储结构 (1)2.2 基本操作 (1)3 详细设计 (2)3.1 流程图 (2)3.2 源程序 (7)4 测试 (12)5 课程设计总结 (19)6参考书目: (20)1 课程设计的目的1.1 课程设计的目的更好的掌握数据结构这门课程,会用数据结构的基本思想及算法解决实际问题。

更好的掌握循环链表,能进行各种基本的操作,提高编程能力。

1.2 课程设计的题目循环单链表(附加头结点,引用)1.3 题目要求实现附加头结点循环单链表的基本操作:创建空表、输出、求表长、取元素、查找、替换、插入、删除、清空。

2 概要设计2.1 存储结构存储结构L data next data next data next datnexttypedef struct node{datatype data;/*数据域*/struct node *next;/*指针域*/}LNode,*LinkList;/*结点及结点的地址*/2.2 基本操作创建空表、输出、求表长、取元素、查找、替换、插入、删除、清空。

3 详细设计3.1 流程图各个算法的设计如下:1.主函数:2.主菜单用于进行指示进行各种操作,是与每个函数都相联系的一个函数3.显示链表先让指针指向首元结点,在判断该指针是否为头指针,不是则输入数据,实则退出4.求表长先求表的初始长,在判断链表是否为空,不是则len自加,否则结束先求表长,在判断Index < 1 || Index > len,为否则循环,一直活得该数据6.查找求表长,在判断链表是否为空,是则结束,否则判断要查找的数据是否在链表中,是则成功判断要替换的位置是否在链表范围中,是则循环找到要替换的数据替换,否则结束判断将要插入的位置是否在链表范围内,是则循环将要插入的数据插入,否则结束9.删除判断链表是否为空,否则删除该结点,是则结束10.清空判断聊表是够为空,否则依次释放空间,否则结束3.2 源程序#include <iostream>using namespace std;typedef int ElemType;typedef struct node{ElemType data;struct node *next;}LNode,*LinkList,*pNODE;// 创建一个有头结点的空循环表。

LinkList InitList(void){pNODE head = new LNode;head->next = head;return head;}// 头插法。

将给定结点插在链表头部。

void InsertHead(LinkList head,pNODE anode) {anode->next = head->next;head->next = anode;}// 返回链表长度。

int ListLen(LinkList head){int len = 0;pNODE p = head;while(p->next != head){++len;p = p->next;}return len;}// 查找。

成功返回1,否则返回0。

int ListSearch(LinkList head, ElemType data){pNODE p = head;while(p->next != head){if(p->next->data == data)return true;p = p->next;}return 0;}// 获取指定索引号的数据。

void GetData(LinkList head,int Index,ElemType data){pNODE p = head;int i,len = ListLen(head);if(Index < 1 || Index > len)cout <<"获取失败" <<endl;for(i = 0; i <Index; ++i,p = p->next);data = p->data;cout <<"获取成功,其值为:"<<data <<endl; }// 用给定结点替换指定索引的结点。

void NodeReplace(LinkList head, int Index, int data){pNODE p = head;int i,len = ListLen(head);if(Index < 1 || Index > len)cout <<"错误" <<endl;for(i = 0; i <Index; ++i,p = p->next);p->data=data;cout <<"替换成功" <<endl;}//插入结点void ListInsert(LinkList head,int Index,int data){pNODE s,p=head;int i,len = ListLen(head);if(Index < 1 || Index > len)cout <<"错误" <<endl;for(i=1;i<Index;++i,p=p->next);s=new LNode;s->data=data;s->next=p->next;p->next=s;cout <<"插入成功" <<endl;}// 删除数据域为data的结点。

成功返回1,否则返回0。

int NodeErase(LinkList head,ElemType data){pNODE q,p = head;while(p->next != head){if(p->next->data == data){q = p->next;p->next = q->next;delete q;return 1;}p = p->next;}return 0;}// 释放链表void ListDestroy(LinkList head){pNODE q,p = head;while(p->next != head){q = p->next;p->next = q->next;delete q;}delete head;cout <<"释放成功" <<endl;}// 显示链表void ListShow(LinkList head){pNODE p = head->next;while(p != head){cout <<" "<<p->data;p = p->next;}cout <<endl;}void Menu(LinkList head){cout <<"***********************************循环链表*************************************" <<endl;cout<<"***************************************************************** ***************" <<endl;cout <<"*****************1显示链表2求表长3取元素4查找5替换6插入7删除8清空9退出**********" <<endl;cout<<"***************************************************************** ***************" <<endl;cout<<"请选择您需要的操作:"<<endl;int xz,Index,data;cin >>xz;switch(xz){case 1:ListShow(head);system("pause");system("cls");Menu(head);break;case 2:cout <<"链表长度为:" <<ListLen(head) <<endl;system("pause");system("cls");Menu(head);break;case 3:cout <<"请输入要获取的数据的位置:" <<endl;cin >>Index;GetData(head,Index,data);system("pause");system("cls");Menu(head);break;case 4:cout <<"请输入要查找的数据: " <<endl;cin >>data;if(ListSearch(head, data))cout <<"找到了" <<endl;elsecout <<"对不起,没找到" <<data <<endl;system("pause");system("cls");Menu(head);break;case 5:cout <<"请输入要替换的位置,其值为:" <<endl;cin >>Index >>data;NodeReplace(head,Index,data);system("pause");system("cls");Menu(head);break;case 6:cout <<"请输入插入的位置及数值:" <<endl;cin >>Index >>data;ListInsert(head,Index,data);system("pause");system("cls");Menu(head);break;case 7:cout <<"请输入要删除结点的数据: " <<endl;cin >>data;if(NodeErase(head,data))cout <<"成功删除" <<data <<endl;elsecout <<"没有找到" <<data <<endl;system("pause");system("cls");Menu(head);break;case 8:ListDestroy(head);system("pause");system("cls");Menu(head);break;case 0:exit(1);}}int main(){LinkList head = InitList();pNODE anode;int i,n = 10,a[] = {0,1,2,3,4,5,6,7,8,9};for(i = 0; i < n; ++i){ // 头插法anode =new LNode;anode->data = a[i];InsertHead(head,anode);}Menu(head);return 0;}4 测试菜单界面显示各种功能需进行的各种操作,界面如下:选择1时,显示链表中的数据,如图:选择2时,可以得到链表长度,如图:选择3时,输入要获取的数据的位置,成功则如图:选择4时,可以查找元素是否在该链表中,但该功能不能显示出查找到的数据的位置,有所不足,如图:选择5时,可以替换你指定位置的数据,如图:选择1,显示替换指定位置数据后链表中的所有数据,如图:选择6时,可以选择要插入的位置及数值,插入成功,如图:选择1,插入后,链表中所有的数据,如图:选择7时,可以删除你要删除的数据,成功删除则如图:选择7,删除失败,如图:选择8时,可以清空链表,如图:5 课程设计总结通过这次课程设计,我又收获到很多,平时的在做作业时,因为题形与结构都是很简单的,并且每一章的内容都是有相应的例题可以参考,所以在做题时没有遇到过很麻烦的问题,而这次不同了,一个课题拿到手时,给我的感觉是无从下手,而且要求很多,使得题目要求更大了.通过本次课程设计,我最大的收获就是自己的动手能力得到了很大的提升,我发现只有自己动手才能更好的了解到自己的知识漏洞,很多小问题可能对代码的编写都有很大影响,像在编写过程中我有时漏掉半撇括号,而在查找时就相当费力,所以多敲代码很重要啊。

相关文档
最新文档